Initial checkin.

diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..2997cdd
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,255 @@
+## Process this file with automake to produce Makefile.in
+
+if GCC
+# These are good warnings to turn on by default
+AM_CXXFLAGS = $(PTHREAD_CFLAGS) -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+else
+AM_CXXFLAGS = $(PTHREAD_CFLAGS)
+endif
+
+AM_LDFLAGS = $(PTHREAD_CFLAGS)
+
+# If I say "dist_include_DATA", automake complains that $(includedir) is not
+# a "legitimate" directory for DATA.  Screw you, automake.
+protodir = $(includedir)
+nobase_dist_proto_DATA = google/protobuf/descriptor.proto
+
+# Not sure why these don't get cleaned automatically.
+clean-local:
+	rm -f *.loT
+
+CLEANFILES = $(protoc_outputs) unittest_proto_middleman
+
+MAINTAINERCLEANFILES =   \
+  Makefile.in
+
+nobase_include_HEADERS =                                       \
+  google/protobuf/stubs/common.h                               \
+  google/protobuf/descriptor.h                                 \
+  google/protobuf/descriptor.pb.h                              \
+  google/protobuf/descriptor_database.h                        \
+  google/protobuf/dynamic_message.h                            \
+  google/protobuf/extension_set.h                              \
+  google/protobuf/generated_message_reflection.h               \
+  google/protobuf/message.h                                    \
+  google/protobuf/reflection_ops.h                             \
+  google/protobuf/repeated_field.h                             \
+  google/protobuf/service.h                                    \
+  google/protobuf/text_format.h                                \
+  google/protobuf/unknown_field_set.h                          \
+  google/protobuf/wire_format.h                                \
+  google/protobuf/wire_format_inl.h                            \
+  google/protobuf/io/coded_stream.h                            \
+  google/protobuf/io/printer.h                                 \
+  google/protobuf/io/tokenizer.h                               \
+  google/protobuf/io/zero_copy_stream.h                        \
+  google/protobuf/io/zero_copy_stream_impl.h                   \
+  google/protobuf/compiler/code_generator.h                    \
+  google/protobuf/compiler/command_line_interface.h            \
+  google/protobuf/compiler/importer.h                          \
+  google/protobuf/compiler/parser.h                            \
+  google/protobuf/compiler/cpp/cpp_generator.h                 \
+  google/protobuf/compiler/java/java_generator.h               \
+  google/protobuf/compiler/python/python_generator.h
+
+lib_LTLIBRARIES = libprotobuf.la libprotoc.la
+
+libprotobuf_la_LIBADD = $(PTHREAD_LIBS)
+libprotobuf_la_LDFLAGS = -version-info 0:0:0
+libprotobuf_la_SOURCES =                                       \
+  google/protobuf/stubs/common.cc                              \
+  google/protobuf/stubs/hash.cc                                \
+  google/protobuf/stubs/hash.h                                 \
+  google/protobuf/stubs/map-util.cc                            \
+  google/protobuf/stubs/map-util.h                             \
+  google/protobuf/stubs/stl_util-inl.cc                        \
+  google/protobuf/stubs/stl_util-inl.h                         \
+  google/protobuf/stubs/substitute.cc                          \
+  google/protobuf/stubs/substitute.h                           \
+  google/protobuf/stubs/strutil.cc                             \
+  google/protobuf/stubs/strutil.h                              \
+  google/protobuf/descriptor.cc                                \
+  google/protobuf/descriptor.pb.cc                             \
+  google/protobuf/descriptor_database.cc                       \
+  google/protobuf/dynamic_message.cc                           \
+  google/protobuf/extension_set.cc                             \
+  google/protobuf/generated_message_reflection.cc              \
+  google/protobuf/message.cc                                   \
+  google/protobuf/reflection_ops.cc                            \
+  google/protobuf/repeated_field.cc                            \
+  google/protobuf/service.cc                                   \
+  google/protobuf/text_format.cc                               \
+  google/protobuf/unknown_field_set.cc                         \
+  google/protobuf/wire_format.cc                               \
+  google/protobuf/io/coded_stream.cc                           \
+  google/protobuf/io/printer.cc                                \
+  google/protobuf/io/tokenizer.cc                              \
+  google/protobuf/io/zero_copy_stream.cc                       \
+  google/protobuf/io/zero_copy_stream_impl.cc                  \
+  google/protobuf/compiler/importer.cc                         \
+  google/protobuf/compiler/parser.cc
+
+libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la
+libprotoc_la_LDFLAGS = -version-info 0:0:0
+libprotoc_la_SOURCES =                                         \
+  google/protobuf/compiler/code_generator.cc                   \
+  google/protobuf/compiler/command_line_interface.cc           \
+  google/protobuf/compiler/cpp/cpp_enum.cc                     \
+  google/protobuf/compiler/cpp/cpp_enum.h                      \
+  google/protobuf/compiler/cpp/cpp_enum_field.cc               \
+  google/protobuf/compiler/cpp/cpp_enum_field.h                \
+  google/protobuf/compiler/cpp/cpp_extension.cc                \
+  google/protobuf/compiler/cpp/cpp_extension.h                 \
+  google/protobuf/compiler/cpp/cpp_field.cc                    \
+  google/protobuf/compiler/cpp/cpp_field.h                     \
+  google/protobuf/compiler/cpp/cpp_file.cc                     \
+  google/protobuf/compiler/cpp/cpp_file.h                      \
+  google/protobuf/compiler/cpp/cpp_generator.cc                \
+  google/protobuf/compiler/cpp/cpp_helpers.cc                  \
+  google/protobuf/compiler/cpp/cpp_helpers.h                   \
+  google/protobuf/compiler/cpp/cpp_message.cc                  \
+  google/protobuf/compiler/cpp/cpp_message.h                   \
+  google/protobuf/compiler/cpp/cpp_message_field.cc            \
+  google/protobuf/compiler/cpp/cpp_message_field.h             \
+  google/protobuf/compiler/cpp/cpp_primitive_field.cc          \
+  google/protobuf/compiler/cpp/cpp_primitive_field.h           \
+  google/protobuf/compiler/cpp/cpp_service.cc                  \
+  google/protobuf/compiler/cpp/cpp_service.h                   \
+  google/protobuf/compiler/cpp/cpp_string_field.cc             \
+  google/protobuf/compiler/cpp/cpp_string_field.h              \
+  google/protobuf/compiler/java/java_enum.cc                   \
+  google/protobuf/compiler/java/java_enum.h                    \
+  google/protobuf/compiler/java/java_enum_field.cc             \
+  google/protobuf/compiler/java/java_enum_field.h              \
+  google/protobuf/compiler/java/java_extension.cc              \
+  google/protobuf/compiler/java/java_extension.h               \
+  google/protobuf/compiler/java/java_field.cc                  \
+  google/protobuf/compiler/java/java_field.h                   \
+  google/protobuf/compiler/java/java_file.cc                   \
+  google/protobuf/compiler/java/java_file.h                    \
+  google/protobuf/compiler/java/java_generator.cc              \
+  google/protobuf/compiler/java/java_helpers.cc                \
+  google/protobuf/compiler/java/java_helpers.h                 \
+  google/protobuf/compiler/java/java_message.cc                \
+  google/protobuf/compiler/java/java_message.h                 \
+  google/protobuf/compiler/java/java_message_field.cc          \
+  google/protobuf/compiler/java/java_message_field.h           \
+  google/protobuf/compiler/java/java_primitive_field.cc        \
+  google/protobuf/compiler/java/java_primitive_field.h         \
+  google/protobuf/compiler/java/java_service.cc                \
+  google/protobuf/compiler/java/java_service.h                 \
+  google/protobuf/compiler/python/python_generator.cc
+
+bin_PROGRAMS = protoc
+protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la
+protoc_SOURCES = google/protobuf/compiler/main.cc
+
+# Tests ==============================================================
+
+protoc_inputs =                                                \
+  google/protobuf/unittest.proto                               \
+  google/protobuf/unittest_import.proto                        \
+  google/protobuf/unittest_mset.proto                          \
+  google/protobuf/unittest_optimize_for.proto                  \
+  google/protobuf/unittest_embed_optimize_for.proto            \
+  google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
+
+EXTRA_DIST =                                                   \
+  $(protoc_inputs)                                             \
+  solaris/libstdc++.la                                         \
+  google/protobuf/testdata/golden_message                      \
+  google/protobuf/testdata/text_format_unittest_data.txt       \
+  google/protobuf/testdata/text_format_unittest_extensions_data.txt  \
+  google/protobuf/package_info.h                               \
+  google/protobuf/io/package_info.h                            \
+  google/protobuf/compiler/package_info.h                      \
+  gtest/CHANGES                                                \
+  gtest/CONTRIBUTORS                                           \
+  gtest/COPYING                                                \
+  gtest/README                                                 \
+  gtest/gen_gtest_pred_impl.py
+
+protoc_outputs =                                               \
+  google/protobuf/unittest.pb.cc                               \
+  google/protobuf/unittest.pb.h                                \
+  google/protobuf/unittest_import.pb.cc                        \
+  google/protobuf/unittest_import.pb.h                         \
+  google/protobuf/unittest_mset.pb.cc                          \
+  google/protobuf/unittest_mset.pb.h                           \
+  google/protobuf/unittest_optimize_for.pb.cc                  \
+  google/protobuf/unittest_optimize_for.pb.h                   \
+  google/protobuf/unittest_embed_optimize_for.pb.cc            \
+  google/protobuf/unittest_embed_optimize_for.pb.h             \
+  google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc  \
+  google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h
+
+BUILT_SOURCES = $(protoc_outputs)
+
+# This rule is a little weird.  The first prereq is the protoc executable
+# and the rest are its inputs.  Therefore, $^ -- which expands to the
+# list of prereqs -- is actually a valid command.  We have to place "./" in
+# front of it in case protoc is in the current directory.  protoc allows
+# flags to appear after input file names, so we happily stick the flags on
+# the end.
+#
+# For reference, if we didn't have to worry about VPATH (i.e., building from
+# a directory other than the package root), we could have just written this:
+#   ./protoc$(EXEEXT) -I$(srcdir) --cpp_out=. $(protoc_inputs)
+unittest_proto_middleman: protoc$(EXEEXT) $(protoc_inputs)
+	./$^ -I$(srcdir) --cpp_out=.
+	touch unittest_proto_middleman
+
+$(protoc_outputs): unittest_proto_middleman
+
+noinst_PROGRAMS = protobuf-test
+protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la
+protobuf_test_SOURCES =                                        \
+  google/protobuf/stubs/common_unittest.cc                     \
+  google/protobuf/stubs/strutil_unittest.cc                    \
+  google/protobuf/descriptor_database_unittest.cc              \
+  google/protobuf/descriptor_unittest.cc                       \
+  google/protobuf/dynamic_message_unittest.cc                  \
+  google/protobuf/extension_set_unittest.cc                    \
+  google/protobuf/generated_message_reflection_unittest.cc     \
+  google/protobuf/message_unittest.cc                          \
+  google/protobuf/reflection_ops_unittest.cc                   \
+  google/protobuf/repeated_field_unittest.cc                   \
+  google/protobuf/text_format_unittest.cc                      \
+  google/protobuf/unknown_field_set_unittest.cc                \
+  google/protobuf/wire_format_unittest.cc                      \
+  google/protobuf/io/coded_stream_unittest.cc                  \
+  google/protobuf/io/printer_unittest.cc                       \
+  google/protobuf/io/tokenizer_unittest.cc                     \
+  google/protobuf/io/zero_copy_stream_unittest.cc              \
+  google/protobuf/compiler/command_line_interface_unittest.cc  \
+  google/protobuf/compiler/importer_unittest.cc                \
+  google/protobuf/compiler/parser_unittest.cc                  \
+  google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc       \
+  google/protobuf/compiler/cpp/cpp_unittest.cc                 \
+  google/protobuf/test_util.cc                                 \
+  google/protobuf/test_util.h                                  \
+  google/protobuf/testing/googletest.cc                        \
+  google/protobuf/testing/googletest.h                         \
+  google/protobuf/testing/file.cc                              \
+  google/protobuf/testing/file.h                               \
+  gtest/gtest.cc                                               \
+  gtest/gtest.h                                                \
+  gtest/gtest-death-test.cc                                    \
+  gtest/gtest-death-test.h                                     \
+  gtest/gtest-filepath.cc                                      \
+  gtest/gtest-internal-inl.h                                   \
+  gtest/gtest-message.h                                        \
+  gtest/gtest-port.cc                                          \
+  gtest/gtest-spi.h                                            \
+  gtest/gtest_main.cc                                          \
+  gtest/gtest_pred_impl.h                                      \
+  gtest/gtest_prod.h                                           \
+  gtest/internal/gtest-death-test-internal.h                   \
+  gtest/internal/gtest-filepath.h                              \
+  gtest/internal/gtest-internal.h                              \
+  gtest/internal/gtest-port.h                                  \
+  gtest/internal/gtest-string.h
+
+nodist_protobuf_test_SOURCES = $(protoc_outputs)
+
+TESTS = protobuf-test
diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc
new file mode 100644
index 0000000..d3a051d
--- /dev/null
+++ b/src/google/protobuf/compiler/code_generator.cc
@@ -0,0 +1,32 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+CodeGenerator::~CodeGenerator() {}
+OutputDirectory::~OutputDirectory() {}
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h
new file mode 100644
index 0000000..8f9938e
--- /dev/null
+++ b/src/google/protobuf/compiler/code_generator.h
@@ -0,0 +1,98 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Defines the abstract interface implemented by each of the language-specific
+// code generators.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
+
+#include <google/protobuf/stubs/common.h>
+#include <string>
+
+namespace google {
+namespace protobuf {
+
+namespace io { class ZeroCopyOutputStream; }
+class FileDescriptor;
+
+namespace compiler {
+
+// Defined in this file.
+class CodeGenerator;
+class OutputDirectory;
+
+// The abstract interface to a class which generates code implementing a
+// particular proto file in a particular language.  A number of these may
+// be registered with CommandLineInterface to support various languages.
+class LIBPROTOC_EXPORT CodeGenerator {
+ public:
+  inline CodeGenerator() {}
+  virtual ~CodeGenerator();
+
+  // Generates code for the given proto file, generating one or more files in
+  // the given output directory.
+  //
+  // A parameter to be passed to the generator can be specified on the
+  // command line.  This is intended to be used by Java and similar languages
+  // to specify which specific class from the proto file is to be generated,
+  // though it could have other uses as well.  It is empty if no parameter was
+  // given.
+  //
+  // Returns true if successful.  Otherwise, sets *error to a description of
+  // the problem (e.g. "invalid parameter") and returns false.
+  virtual bool Generate(const FileDescriptor* file,
+                        const string& parameter,
+                        OutputDirectory* output_directory,
+                        string* error) const = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodeGenerator);
+};
+
+// CodeGenerators generate one or more files in a given directory.  This
+// abstract interface represents the directory to which the CodeGenerator is
+// to write.
+class LIBPROTOC_EXPORT OutputDirectory {
+ public:
+  inline OutputDirectory() {}
+  virtual ~OutputDirectory();
+
+  // Opens the given file, truncating it if it exists, and returns a
+  // ZeroCopyOutputStream that writes to the file.  The caller takes ownership
+  // of the returned object.  This method never fails (a dummy stream will be
+  // returned instead).
+  //
+  // The filename given should be relative to the root of the source tree.
+  // E.g. the C++ generator, when generating code for "foo/bar.proto", will
+  // generate the files "foo/bar.pb2.h" and "foo/bar.pb2.cc"; note that
+  // "foo/" is included in these filenames.  The filename is not allowed to
+  // contain "." or ".." components.
+  virtual io::ZeroCopyOutputStream* Open(const string& filename) = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OutputDirectory);
+};
+
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
new file mode 100644
index 0000000..68e88a8
--- /dev/null
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -0,0 +1,579 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  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>
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <iostream>
+
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#if defined(_WIN32)
+#define mkdir(name, mode) mkdir(name)
+#ifndef W_OK
+#define W_OK 02  // not defined by MSVC for whatever reason
+#endif
+#ifndef F_OK
+#define F_OK 00  // not defined by MSVC for whatever reason
+#endif
+#endif
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0     // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+namespace {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static const char* kPathSeparator = ";";
+#else
+static const char* kPathSeparator = ":";
+#endif
+}  // namespace
+
+// A MultiFileErrorCollector that prints errors to stderr.
+class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector {
+ public:
+  ErrorPrinter() {}
+  ~ErrorPrinter() {}
+
+  // implements MultiFileErrorCollector ------------------------------
+  void AddError(const string& filename, int line, int column,
+                const string& message) {
+    // Users typically expect 1-based line/column numbers, so we add 1
+    // to each here.
+    cerr << filename;
+    if (line != -1) {
+      cerr << ":" << (line + 1) << ":" << (column + 1);
+    }
+    cerr << ": " << message << endl;
+  }
+};
+
+// -------------------------------------------------------------------
+
+// An OutputDirectory implementation that writes to disk.
+class CommandLineInterface::DiskOutputDirectory : public OutputDirectory {
+ public:
+  DiskOutputDirectory(const string& root);
+  ~DiskOutputDirectory();
+
+  bool VerifyExistence();
+
+  inline bool had_error() { return had_error_; }
+  inline void set_had_error(bool value) { had_error_ = value; }
+
+  // implements OutputDirectory --------------------------------------
+  io::ZeroCopyOutputStream* Open(const string& filename);
+
+ private:
+  string root_;
+  bool had_error_;
+};
+
+// A FileOutputStream that checks for errors in the destructor and reports
+// them.  We extend FileOutputStream via wrapping rather than inheritance
+// for two reasons:
+// 1) Implementation inheritance is evil.
+// 2) We need to close the file descriptor *after* the FileOutputStream's
+//    destructor is run to make sure it flushes the file contents.
+class CommandLineInterface::ErrorReportingFileOutput
+    : public io::ZeroCopyOutputStream {
+ public:
+  ErrorReportingFileOutput(int file_descriptor,
+                           const string& filename,
+                           DiskOutputDirectory* directory);
+  ~ErrorReportingFileOutput();
+
+  // implements ZeroCopyOutputStream ---------------------------------
+  bool Next(void** data, int* size) { return file_stream_->Next(data, size); }
+  void BackUp(int count)            {        file_stream_->BackUp(count);    }
+  int64 ByteCount() const           { return file_stream_->ByteCount();      }
+
+ private:
+  scoped_ptr<io::FileOutputStream> file_stream_;
+  int file_descriptor_;
+  string filename_;
+  DiskOutputDirectory* directory_;
+};
+
+// -------------------------------------------------------------------
+
+CommandLineInterface::DiskOutputDirectory::DiskOutputDirectory(
+    const string& root)
+  : root_(root), had_error_(false) {
+  // Add a '/' to the end if it doesn't already have one.  But don't add a
+  // '/' to an empty string since this probably means the current directory.
+  if (!root_.empty() && root[root_.size() - 1] != '/') {
+    root_ += '/';
+  }
+}
+
+CommandLineInterface::DiskOutputDirectory::~DiskOutputDirectory() {
+}
+
+bool CommandLineInterface::DiskOutputDirectory::VerifyExistence() {
+  if (!root_.empty()) {
+    // Make sure the directory exists.  If it isn't a directory, this will fail
+    // because we added a '/' to the end of the name in the constructor.
+    if (access(root_.c_str(), W_OK) == -1) {
+      cerr << root_ << ": " << strerror(errno) << endl;
+      return false;
+    }
+  }
+
+  return true;
+}
+
+io::ZeroCopyOutputStream* CommandLineInterface::DiskOutputDirectory::Open(
+    const string& filename) {
+  // Recursively create parent directories to the output file.
+  vector<string> parts;
+  SplitStringUsing(filename, "/", &parts);
+  string path_so_far = root_;
+  for (int i = 0; i < parts.size() - 1; i++) {
+    path_so_far += parts[i];
+    if (mkdir(path_so_far.c_str(), 0777) != 0) {
+      if (errno != EEXIST) {
+        cerr << filename << ": while trying to create directory "
+             << path_so_far << ": " << strerror(errno) << endl;
+        had_error_ = true;
+        // Return a dummy stream.
+        return new io::ArrayOutputStream(NULL, 0);
+      }
+    }
+    path_so_far += '/';
+  }
+
+  // Create the output file.
+  int file_descriptor;
+  do {
+    file_descriptor =
+      open((root_ + filename).c_str(),
+           O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0777);
+  } while (file_descriptor < 0 && errno == EINTR);
+
+  if (file_descriptor < 0) {
+    // Failed to open.
+    cerr << filename << ": " << strerror(errno) << endl;
+    had_error_ = true;
+    // Return a dummy stream.
+    return new io::ArrayOutputStream(NULL, 0);
+  }
+
+  return new ErrorReportingFileOutput(file_descriptor, filename, this);
+}
+
+CommandLineInterface::ErrorReportingFileOutput::ErrorReportingFileOutput(
+    int file_descriptor,
+    const string& filename,
+    DiskOutputDirectory* directory)
+  : file_stream_(new io::FileOutputStream(file_descriptor)),
+    file_descriptor_(file_descriptor),
+    filename_(filename),
+    directory_(directory) {}
+
+CommandLineInterface::ErrorReportingFileOutput::~ErrorReportingFileOutput() {
+  // Check if we had any errors while writing.
+  if (file_stream_->GetErrno() != 0) {
+    cerr << filename_ << ": " << strerror(file_stream_->GetErrno()) << endl;
+    directory_->set_had_error(true);
+  }
+
+  // Close the file stream.
+  if (!file_stream_->Close()) {
+    cerr << filename_ << ": " << strerror(file_stream_->GetErrno()) << endl;
+    directory_->set_had_error(true);
+  }
+}
+
+// ===================================================================
+
+CommandLineInterface::CommandLineInterface()
+  : disallow_services_(false),
+    inputs_are_proto_path_relative_(false) {}
+CommandLineInterface::~CommandLineInterface() {}
+
+void CommandLineInterface::RegisterGenerator(const string& flag_name,
+                                             CodeGenerator* generator,
+                                             const string& help_text) {
+  GeneratorInfo info;
+  info.generator = generator;
+  info.help_text = help_text;
+  generators_[flag_name] = info;
+}
+
+int CommandLineInterface::Run(int argc, const char* const argv[]) {
+  Clear();
+  if (!ParseArguments(argc, argv)) return -1;
+
+  // Set up the source tree.
+  DiskSourceTree source_tree;
+  for (int i = 0; i < proto_path_.size(); i++) {
+    source_tree.MapPath(proto_path_[i].first, proto_path_[i].second);
+  }
+
+  // Map input files to virtual paths if necessary.
+  if (!inputs_are_proto_path_relative_) {
+    if (!MakeInputsBeProtoPathRelative(&source_tree)) {
+      return -1;
+    }
+  }
+
+  // Allocate the Importer.
+  ErrorPrinter error_collector;
+  DescriptorPool pool;
+  Importer importer(&source_tree, &error_collector);
+
+  // 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;
+
+    // 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;
+    }
+
+    // Generate output files.
+    for (int i = 0; i < output_directives_.size(); i++) {
+      if (!GenerateOutput(parsed_file, output_directives_[i])) {
+        return -1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+void CommandLineInterface::Clear() {
+  proto_path_.clear();
+  input_files_.clear();
+  output_directives_.clear();
+}
+
+bool CommandLineInterface::MakeInputsBeProtoPathRelative(
+    DiskSourceTree* source_tree) {
+  for (int i = 0; i < input_files_.size(); i++) {
+    string virtual_file, shadowing_disk_file;
+    switch (source_tree->DiskFileToVirtualFile(
+        input_files_[i], &virtual_file, &shadowing_disk_file)) {
+      case DiskSourceTree::SUCCESS:
+        input_files_[i] = virtual_file;
+        break;
+      case DiskSourceTree::SHADOWED:
+        cerr << input_files_[i] << ": Input is shadowed in the --proto_path "
+                "by \"" << shadowing_disk_file << "\".  Either use the latter "
+                "file as your input or reorder the --proto_path so that the "
+                "former file's location comes first." << endl;
+        return false;
+      case DiskSourceTree::CANNOT_OPEN:
+        cerr << input_files_[i] << ": " << strerror(errno) << endl;
+        return false;
+      case DiskSourceTree::NO_MAPPING:
+        // First check if the file exists at all.
+        if (access(input_files_[i].c_str(), F_OK) < 0) {
+          // File does not even exist.
+          cerr << input_files_[i] << ": " << strerror(ENOENT) << endl;
+        } else {
+          cerr << input_files_[i] << ": File does not reside within any path "
+                  "specified using --proto_path (or -I).  You must specify a "
+                  "--proto_path which encompasses this file." << endl;
+        }
+        return false;
+    }
+  }
+
+  return true;
+}
+
+bool CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
+  executable_name_ = argv[0];
+
+  // Iterate through all arguments and parse them.
+  for (int i = 1; i < argc; i++) {
+    string name, value;
+
+    if (ParseArgument(argv[i], &name, &value)) {
+      // Retured true => Use the next argument as the flag value.
+      if (i + 1 == argc || argv[i+1][0] == '-') {
+        cerr << "Missing value for flag: " << name << endl;
+        return false;
+      } else {
+        ++i;
+        value = argv[i];
+      }
+    }
+
+    if (!InterpretArgument(name, value)) return false;
+  }
+
+  // If no --proto_path was given, use the current working directory.
+  if (proto_path_.empty()) {
+    proto_path_.push_back(make_pair("", "."));
+  }
+
+  // Check some errror cases.
+  if (input_files_.empty()) {
+    cerr << "Missing input file." << endl;
+    return false;
+  }
+  if (output_directives_.empty()) {
+    cerr << "Missing output directives." << endl;
+    return false;
+  }
+
+  return true;
+}
+
+bool CommandLineInterface::ParseArgument(const char* arg,
+                                         string* name, string* value) {
+  bool parsed_value = false;
+
+  if (arg[0] != '-') {
+    // Not a flag.
+    name->clear();
+    parsed_value = true;
+    *value = arg;
+  } else if (arg[1] == '-') {
+    // Two dashes:  Multi-character name, with '=' separating name and
+    //   value.
+    const char* equals_pos = strchr(arg, '=');
+    if (equals_pos != NULL) {
+      *name = string(arg, equals_pos - arg);
+      *value = equals_pos + 1;
+      parsed_value = true;
+    } else {
+      *name = arg;
+    }
+  } else {
+    // One dash:  One-character name, all subsequent characters are the
+    //   value.
+    if (arg[1] == '\0') {
+      // arg is just "-".  We treat this as an input file, except that at
+      // present this will just lead to a "file not found" error.
+      name->clear();
+      *value = arg;
+      parsed_value = true;
+    } else {
+      *name = string(arg, 2);
+      *value = arg + 2;
+      parsed_value = !value->empty();
+    }
+  }
+
+  // Need to return true iff the next arg should be used as the value for this
+  // one, false otherwise.
+
+  if (parsed_value) {
+    // We already parsed a value for this flag.
+    return false;
+  }
+
+  if (*name == "-h" || *name == "--help" ||
+      *name == "--disallow_services" ||
+      *name == "--version") {
+    // 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.
+    return false;
+  }
+
+  // Next argument is the flag value.
+  return true;
+}
+
+bool CommandLineInterface::InterpretArgument(const string& name,
+                                             const string& value) {
+  if (name.empty()) {
+    // Not a flag.  Just a filename.
+    if (value.empty()) {
+      cerr << "You seem to have passed an empty string as one of the "
+              "arguments to " << executable_name_ << ".  This is actually "
+              "sort of hard to do.  Congrats.  Unfortunately it is not valid "
+              "input so the program is going to die now." << endl;
+      return false;
+    }
+
+    input_files_.push_back(value);
+
+  } else if (name == "-I" || name == "--proto_path") {
+    // Java's -classpath (and some other languages) delimits path components
+    // with colons.  Let's accept that syntax too just to make things more
+    // intuitive.
+    vector<string> parts;
+    SplitStringUsing(value, kPathSeparator, &parts);
+
+    for (int i = 0; i < parts.size(); i++) {
+      string virtual_path;
+      string disk_path;
+
+      int equals_pos = parts[i].find_first_of('=');
+      if (equals_pos == string::npos) {
+        virtual_path = "";
+        disk_path = parts[i];
+      } else {
+        virtual_path = parts[i].substr(0, equals_pos);
+        disk_path = parts[i].substr(equals_pos + 1);
+      }
+
+      if (disk_path.empty()) {
+        cerr << "--proto_path passed empty directory name.  (Use \".\" for "
+                "current directory.)" << endl;
+        return false;
+      }
+
+      // Make sure disk path exists, warn otherwise.
+      if (access(disk_path.c_str(), F_OK) < 0) {
+        cerr << disk_path << ": warning: directory does not exist." << endl;
+      }
+
+      proto_path_.push_back(make_pair(virtual_path, disk_path));
+    }
+
+  } else if (name == "-h" || name == "--help") {
+    PrintHelpText();
+    return false;  // Exit without running compiler.
+
+  } else if (name == "--version") {
+    if (!version_info_.empty()) {
+      cout << version_info_ << endl;
+    }
+    cout << "libprotoc "
+         << protobuf::internal::VersionString(GOOGLE_PROTOBUF_VERSION)
+         << endl;
+    return false;  // Exit without running compiler.
+
+  } else if (name == "--disallow_services") {
+    disallow_services_ = true;
+
+  } else {
+    // Some other flag.  Look it up in the generators list.
+    GeneratorMap::const_iterator iter = generators_.find(name);
+    if (iter == generators_.end()) {
+      cerr << "Unknown flag: " << name << endl;
+      return false;
+    }
+
+    // It's an output flag.  Add it to the output directives.
+    OutputDirective directive;
+    directive.name = name;
+    directive.generator = iter->second.generator;
+
+    // Split value at ':' to separate the generator parameter from the
+    // filename.
+    vector<string> parts;
+    SplitStringUsing(value, ":", &parts);
+
+    if (parts.size() == 1) {
+      directive.output_location = parts[0];
+    } else if (parts.size() == 2) {
+      directive.parameter = parts[0];
+      directive.output_location = parts[1];
+    } else {
+      cerr << "Invalid value for flag " << name << "." << endl;
+      return false;
+    }
+
+    output_directives_.push_back(directive);
+  }
+
+  return true;
+}
+
+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"
+"  -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;
+
+  for (GeneratorMap::iterator iter = generators_.begin();
+       iter != generators_.end(); ++iter) {
+    // FIXME(kenton):  If the text is long enough it will wrap, which is ugly,
+    //   but fixing this nicely (e.g. splitting on spaces) is probably more
+    //   trouble than it's worth.
+    cerr << "  " << iter->first << "=OUT_DIR "
+         << string(19 - iter->first.size(), ' ')  // Spaces for alignment.
+         << iter->second.help_text << endl;
+  }
+}
+
+bool CommandLineInterface::GenerateOutput(
+    const FileDescriptor* parsed_file,
+    const OutputDirective& output_directive) {
+  // Create the output directory.
+  DiskOutputDirectory output_directory(output_directive.output_location);
+  if (!output_directory.VerifyExistence()) {
+    return false;
+  }
+
+  // Opened successfully.  Write it.
+
+  // Call the generator.
+  string error;
+  if (!output_directive.generator->Generate(
+      parsed_file, output_directive.parameter, &output_directory, &error)) {
+    // Generator returned an error.
+    cerr << output_directive.name << ": " << error << endl;
+    return false;
+  }
+
+  // Check for write errors.
+  if (output_directory.had_error()) {
+    return false;
+  }
+
+  return true;
+}
+
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h
new file mode 100644
index 0000000..d3cae75
--- /dev/null
+++ b/src/google/protobuf/compiler/command_line_interface.h
@@ -0,0 +1,210 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Implements the Protocol Compiler front-end such that it may be reused by
+// custom compilers written to support other languages.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
+#define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
+
+#include <google/protobuf/stubs/common.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <utility>
+
+namespace google {
+namespace protobuf {
+
+class FileDescriptor;        // descriptor.h
+
+namespace compiler {
+
+class CodeGenerator;        // code_generator.h
+class DiskSourceTree;       // importer.h
+
+// This class implements the command-line interface to the protocol compiler.
+// It is designed to make it very easy to create a custom protocol compiler
+// supporting the languages of your choice.  For example, if you wanted to
+// create a custom protocol compiler binary which includes both the regular
+// C++ support plus support for your own custom output "Foo", you would
+// write a class "FooGenerator" which implements the CodeGenerator interface,
+// then write a main() procedure like this:
+//
+//   int main(int argc, char* argv[]) {
+//     google::protobuf::compiler::CommandLineInterface cli;
+//
+//     // Support generation of C++ source and headers.
+//     google::protobuf::compiler::cpp::CppGenerator cpp_generator;
+//     cli.RegisterGenerator("--cpp_out", &cpp_generator,
+//       "Generate C++ source and header.");
+//
+//     // Support generation of Foo code.
+//     FooGenerator foo_generator;
+//     cli.RegisterGenerator("--foo_out", &foo_generator,
+//       "Generate Foo file.");
+//
+//     return cli.Run(argc, argv);
+//   }
+//
+// The compiler is invoked with syntax like:
+//   protoc --cpp_out=outdir --foo_out=outdir --proto_path=src foo.proto
+//
+// For a full description of the command-line syntax, invoke it with --help.
+class LIBPROTOC_EXPORT CommandLineInterface {
+ public:
+  CommandLineInterface();
+  ~CommandLineInterface();
+
+  // Register a code generator for a language.
+  //
+  // Parameters:
+  // * flag_name: The command-line flag used to specify an output file of
+  //   this type.  The name must start with a '-'.  If the name is longer
+  //   than one letter, it must start with two '-'s.
+  // * generator: The CodeGenerator which will be called to generate files
+  //   of this type.
+  // * help_text: Text describing this flag in the --help output.
+  //
+  // Some generators accept extra parameters.  You can specify this parameter
+  // on the command-line by placing it before the output directory, separated
+  // by a colon:
+  //   protoc --foo_out=enable_bar:outdir
+  // The text before the colon is passed to CodeGenerator::Generate() as the
+  // "parameter".
+  void RegisterGenerator(const string& flag_name,
+                         CodeGenerator* generator,
+                         const string& help_text);
+
+  // Run the Protocol Compiler with the given command-line parameters.
+  // Returns the error code which should be returned by main().
+  //
+  // It may not be safe to call Run() in a multi-threaded environment because
+  // it calls strerror().  I'm not sure why you'd want to do this anyway.
+  int Run(int argc, const char* const argv[]);
+
+  // Call SetInputsAreCwdRelative(true) if the input files given on the command
+  // line should be interpreted relative to the proto import path specified
+  // using --proto_path or -I flags.  Otherwise, input file names will be
+  // interpreted relative to the current working directory (or as absolute
+  // paths if they start with '/'), though they must still reside inside
+  // a directory given by --proto_path or the compiler will fail.  The latter
+  // mode is generally more intuitive and easier to use, especially e.g. when
+  // defining implicit rules in Makefiles.
+  void SetInputsAreProtoPathRelative(bool enable) {
+    inputs_are_proto_path_relative_ = enable;
+  }
+
+  // Provides some text which will be printed when the --version flag is
+  // used.  The version of libprotoc will also be printed on the next line
+  // after this text.
+  void SetVersionInfo(const string& text) {
+    version_info_ = text;
+  }
+
+
+ private:
+  // -----------------------------------------------------------------
+
+  class ErrorPrinter;
+  class DiskOutputDirectory;
+  class ErrorReportingFileOutput;
+
+  // Clear state from previous Run().
+  void Clear();
+
+  // Remaps each file in input_files_ so that it is relative to one of the
+  // directories in proto_path_.  Returns false if an error occurred.  This
+  // is only used if inputs_are_proto_path_relative_ is false.
+  bool MakeInputsBeProtoPathRelative(
+    DiskSourceTree* source_tree);
+
+  // Parse all command-line arguments.
+  bool ParseArguments(int argc, const char* const argv[]);
+
+  // Parses a command-line argument into a name/value pair.  Returns
+  // true if the next argument in the argv should be used as the value,
+  // false otherwise.
+  //
+  // Exmaples:
+  //   "-Isrc/protos" ->
+  //     name = "-I", value = "src/protos"
+  //   "--cpp_out=src/foo.pb2.cc" ->
+  //     name = "--cpp_out", value = "src/foo.pb2.cc"
+  //   "foo.proto" ->
+  //     name = "", value = "foo.proto"
+  bool ParseArgument(const char* arg, string* name, string* value);
+
+  // Interprets arguments parsed with ParseArgument.
+  bool InterpretArgument(const string& name, const string& value);
+
+  // Print the --help text to stderr.
+  void PrintHelpText();
+
+  // Generate the given output file from the given input.
+  struct OutputDirective;  // see below
+  bool GenerateOutput(const FileDescriptor* proto_file,
+                      const OutputDirective& output_directive);
+
+  // -----------------------------------------------------------------
+
+  // The name of the executable as invoked (i.e. argv[0]).
+  string executable_name_;
+
+  // Version info set with SetVersionInfo().
+  string version_info_;
+
+  // Map from flag names to registered generators.
+  struct GeneratorInfo {
+    CodeGenerator* generator;
+    string help_text;
+  };
+  typedef map<string, GeneratorInfo> GeneratorMap;
+  GeneratorMap generators_;
+
+  // Stuff parsed from command line.
+  vector<pair<string, string> > proto_path_;  // Search path for proto files.
+  vector<string> input_files_;                // Names of the input proto files.
+
+  // output_directives_ lists all the files we are supposed to output and what
+  // generator to use for each.
+  struct OutputDirective {
+    string name;
+    CodeGenerator* generator;
+    string parameter;
+    string output_location;
+  };
+  vector<OutputDirective> output_directives_;
+
+  // Was the --disallow_services flag used?
+  bool disallow_services_;
+
+  // See SetInputsAreProtoPathRelative().
+  bool inputs_are_proto_path_relative_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface);
+};
+
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
new file mode 100644
index 0000000..1b1458d
--- /dev/null
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -0,0 +1,964 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <vector>
+
+#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/testing/file.h>
+#include <google/protobuf/stubs/strutil.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+
+class CommandLineInterfaceTest : public testing::Test {
+ protected:
+  virtual void SetUp();
+  virtual void TearDown();
+
+  // Runs the CommandLineInterface with the given command line.  The
+  // command is automatically split on spaces, and the string "$tmpdir"
+  // is replaced with TestTempDir().
+  void Run(const string& command);
+
+  // -----------------------------------------------------------------
+  // Methods to set up the test (called before Run()).
+
+  class MockCodeGenerator;
+
+  // Registers a MockCodeGenerator with the given name.
+  MockCodeGenerator* RegisterGenerator(const string& generator_name,
+                                       const string& flag_name,
+                                       const string& filename,
+                                       const string& help_text);
+  MockCodeGenerator* RegisterErrorGenerator(const string& generator_name,
+                                            const string& error_text,
+                                            const string& flag_name,
+                                            const string& filename,
+                                            const string& help_text);
+
+  // Create a temp file within temp_directory_ with the given name.
+  // The containing directory is also created if necessary.
+  void CreateTempFile(const string& name, const string& contents);
+
+  void SetInputsAreProtoPathRelative(bool enable) {
+    cli_.SetInputsAreProtoPathRelative(enable);
+  }
+
+  // -----------------------------------------------------------------
+  // Methods to check the test results (called after Run()).
+
+  // Checks that no text was written to stderr during Run(), and Run()
+  // returned 0.
+  void ExpectNoErrors();
+
+  // Checks that Run() returned non-zero and the stderr output is exactly
+  // the text given.  expected_test may contain references to "$tmpdir",
+  // which will be replaced by the temporary directory path.
+  void ExpectErrorText(const string& expected_text);
+
+  // Checks that Run() returned non-zero and the stderr contains the given
+  // substring.
+  void ExpectErrorSubstring(const string& expected_substring);
+
+  // Returns true if ExpectErrorSubstring(expected_substring) would pass, but
+  // does not fail otherwise.
+  bool HasAlternateErrorSubstring(const string& expected_substring);
+
+  // Checks that MockCodeGenerator::Generate() was called in the given
+  // context.  That is, this tests if the generator with the given name
+  // was called with the given parameter and proto file and produced the
+  // given output file.  This is checked by reading the output file and
+  // checking that it contains the content that MockCodeGenerator would
+  // generate given these inputs.  message_name is the name of the first
+  // message that appeared in the proto file; this is just to make extra
+  // sure that the correct file was parsed.
+  void ExpectGenerated(const string& generator_name,
+                       const string& parameter,
+                       const string& proto_name,
+                       const string& message_name,
+                       const string& output_file);
+
+ private:
+  // The object we are testing.
+  CommandLineInterface cli_;
+
+  // We create a directory within TestTempDir() in order to add extra
+  // protection against accidentally deleting user files (since we recursively
+  // delete this directory during the test).  This is the full path of that
+  // directory.
+  string temp_directory_;
+
+  // The result of Run().
+  int return_code_;
+
+  // The captured stderr output.
+  string error_text_;
+
+  // Pointers which need to be deleted later.
+  vector<MockCodeGenerator*> mock_generators_to_delete_;
+};
+
+// A mock CodeGenerator which outputs information about the context in which
+// it was called, which can then be checked.  Output is written to a filename
+// constructed by concatenating the filename_prefix (given to the constructor)
+// with the proto file name, separated by a '.'.
+class CommandLineInterfaceTest::MockCodeGenerator : public CodeGenerator {
+ public:
+  // Create a MockCodeGenerator whose Generate() method returns true.
+  MockCodeGenerator(const string& name, const string& filename_prefix);
+
+  // Create a MockCodeGenerator whose Generate() method returns false
+  // and sets the error string to the given string.
+  MockCodeGenerator(const string& name, const string& filename_prefix,
+                    const string& error);
+
+  ~MockCodeGenerator();
+
+  void set_expect_write_error(bool value) {
+    expect_write_error_ = value;
+  }
+
+  // implements CodeGenerator ----------------------------------------
+  bool Generate(const FileDescriptor* file,
+                const string& parameter,
+                OutputDirectory* output_directory,
+                string* error) const;
+
+ private:
+  string name_;
+  string filename_prefix_;
+  bool return_error_;
+  string error_;
+  bool expect_write_error_;
+};
+
+// ===================================================================
+
+void CommandLineInterfaceTest::SetUp() {
+  // Most of these tests were written before this option was added, so we
+  // run with the option on (which used to be the only way) except in certain
+  // tests where we turn it off.
+  cli_.SetInputsAreProtoPathRelative(true);
+
+  temp_directory_ = TestTempDir() + "/proto2_cli_test_temp";
+
+  // If the temp directory already exists, it must be left over from a
+  // previous run.  Delete it.
+  if (File::Exists(temp_directory_)) {
+    File::DeleteRecursively(temp_directory_, NULL, NULL);
+  }
+
+  // Create the temp directory.
+  GOOGLE_CHECK(File::CreateDir(temp_directory_.c_str(), DEFAULT_FILE_MODE));
+}
+
+void CommandLineInterfaceTest::TearDown() {
+  // Delete the temp directory.
+  File::DeleteRecursively(temp_directory_, NULL, NULL);
+
+  // Delete all the MockCodeGenerators.
+  for (int i = 0; i < mock_generators_to_delete_.size(); i++) {
+    delete mock_generators_to_delete_[i];
+  }
+  mock_generators_to_delete_.clear();
+}
+
+void CommandLineInterfaceTest::Run(const string& command) {
+  vector<string> args;
+  SplitStringUsing(command, " ", &args);
+
+  scoped_array<const char*> argv(new const char*[args.size()]);
+
+  for (int i = 0; i < args.size(); i++) {
+    args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true);
+    argv[i] = args[i].c_str();
+  }
+
+  CaptureTestStderr();
+
+  return_code_ = cli_.Run(args.size(), argv.get());
+
+  error_text_ = GetCapturedTestStderr();
+}
+
+// -------------------------------------------------------------------
+
+CommandLineInterfaceTest::MockCodeGenerator*
+CommandLineInterfaceTest::RegisterGenerator(
+    const string& generator_name,
+    const string& flag_name,
+    const string& filename,
+    const string& help_text) {
+  MockCodeGenerator* generator =
+    new MockCodeGenerator(generator_name, filename);
+  mock_generators_to_delete_.push_back(generator);
+
+  cli_.RegisterGenerator(flag_name, generator, help_text);
+  return generator;
+}
+
+CommandLineInterfaceTest::MockCodeGenerator*
+CommandLineInterfaceTest::RegisterErrorGenerator(
+    const string& generator_name,
+    const string& error_text,
+    const string& flag_name,
+    const string& filename_prefix,
+    const string& help_text) {
+  MockCodeGenerator* generator =
+    new MockCodeGenerator(generator_name, filename_prefix, error_text);
+  mock_generators_to_delete_.push_back(generator);
+
+  cli_.RegisterGenerator(flag_name, generator, help_text);
+  return generator;
+}
+
+void CommandLineInterfaceTest::CreateTempFile(
+    const string& name,
+    const string& contents) {
+  // Create parent directory, if necessary.
+  string::size_type slash_pos = name.find_last_of('/');
+  if (slash_pos != string::npos) {
+    string dir = name.substr(0, slash_pos);
+    File::RecursivelyCreateDir(temp_directory_ + "/" + dir, 0777);
+  }
+
+  // Write file.
+  string full_name = temp_directory_ + "/" + name;
+  File::WriteStringToFileOrDie(contents, full_name);
+}
+
+// -------------------------------------------------------------------
+
+void CommandLineInterfaceTest::ExpectNoErrors() {
+  EXPECT_EQ(0, return_code_);
+  EXPECT_EQ("", error_text_);
+}
+
+void CommandLineInterfaceTest::ExpectErrorText(const string& expected_text) {
+  EXPECT_NE(0, return_code_);
+  EXPECT_EQ(StringReplace(expected_text, "$tmpdir", temp_directory_, true),
+            error_text_);
+}
+
+void CommandLineInterfaceTest::ExpectErrorSubstring(
+    const string& expected_substring) {
+  EXPECT_NE(0, return_code_);
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
+}
+
+bool CommandLineInterfaceTest::HasAlternateErrorSubstring(
+    const string& expected_substring) {
+  EXPECT_NE(0, return_code_);
+  return error_text_.find(expected_substring) != string::npos;
+}
+
+void CommandLineInterfaceTest::ExpectGenerated(
+    const string& generator_name,
+    const string& parameter,
+    const string& proto_name,
+    const string& message_name,
+    const string& output_file_prefix) {
+  // Open and read the file.
+  string output_file = output_file_prefix + "." + proto_name;
+  string file_contents;
+  ASSERT_TRUE(File::ReadFileToString(temp_directory_ + "/" + output_file,
+                                     &file_contents))
+    << "Failed to open file: " + output_file;
+
+  // Check that the contents are as we expect.
+  string expected_contents =
+    generator_name + ": " + parameter + ", " + proto_name + ", " +
+    message_name + "\n";
+  EXPECT_EQ(expected_contents, file_contents)
+    << "Output file did not have expected contents: " + output_file;
+}
+
+// ===================================================================
+
+CommandLineInterfaceTest::MockCodeGenerator::MockCodeGenerator(
+    const string& name, const string& filename_prefix)
+  : name_(name),
+    filename_prefix_(filename_prefix),
+    return_error_(false),
+    expect_write_error_(false) {
+}
+
+CommandLineInterfaceTest::MockCodeGenerator::MockCodeGenerator(
+    const string& name, const string& filename_prefix, const string& error)
+  : name_(name),
+    filename_prefix_(filename_prefix),
+    return_error_(true),
+    error_(error),
+    expect_write_error_(false) {
+}
+
+CommandLineInterfaceTest::MockCodeGenerator::~MockCodeGenerator() {}
+
+bool CommandLineInterfaceTest::MockCodeGenerator::Generate(
+    const FileDescriptor* file,
+    const string& parameter,
+    OutputDirectory* output_directory,
+    string* error) const {
+  scoped_ptr<io::ZeroCopyOutputStream> output(
+    output_directory->Open(filename_prefix_ + "." + file->name()));
+  io::Printer printer(output.get(), '$');
+  map<string, string> vars;
+  vars["name"] = name_;
+  vars["parameter"] = parameter;
+  vars["proto_name"] = file->name();
+  vars["message_name"] = file->message_type_count() > 0 ?
+    file->message_type(0)->full_name().c_str() : "(none)";
+
+  printer.Print(vars, "$name$: $parameter$, $proto_name$, $message_name$\n");
+
+  if (expect_write_error_) {
+    EXPECT_TRUE(printer.failed());
+  } else {
+    EXPECT_FALSE(printer.failed());
+  }
+
+  *error = error_;
+  return !return_error_;
+}
+
+// ===================================================================
+
+TEST_F(CommandLineInterfaceTest, BasicOutput) {
+  // Test that the common case works.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputs) {
+  // Test parsing multiple input files.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "message Bar {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto bar.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+  ExpectGenerated("test_generator", "", "bar.proto", "Bar", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, CreateDirectory) {
+  // Test that when we output to a sub-directory, it is created.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "bar/baz/output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "",
+                  "foo.proto", "Foo", "bar/baz/output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorParameters) {
+  // Test that generator parameters are correctly parsed from the command line.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --test_out=TestParameter:$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "TestParameter",
+                  "foo.proto", "Foo", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, PathLookup) {
+  // Test that specifying multiple directories in the proto search path works.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("b/bar.proto",
+    "syntax = \"proto2\";\n"
+    "message Bar {}\n");
+  CreateTempFile("a/foo.proto",
+    "syntax = \"proto2\";\n"
+    "import \"bar.proto\";\n"
+    "message Foo {\n"
+    "  optional Bar a = 1;\n"
+    "}\n");
+  CreateTempFile("b/foo.proto", "this should not be parsed\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir/a --proto_path=$tmpdir/b foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) {
+  // Same as PathLookup, but we provide the proto_path in a single flag.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("b/bar.proto",
+    "syntax = \"proto2\";\n"
+    "message Bar {}\n");
+  CreateTempFile("a/foo.proto",
+    "syntax = \"proto2\";\n"
+    "import \"bar.proto\";\n"
+    "message Foo {\n"
+    "  optional Bar a = 1;\n"
+    "}\n");
+  CreateTempFile("b/foo.proto", "this should not be parsed\n");
+
+#undef PATH_SEPARATOR
+#if defined(_WIN32)
+#define PATH_SEPARATOR ";"
+#else
+#define PATH_SEPARATOR ":"
+#endif
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir/a"PATH_SEPARATOR"$tmpdir/b foo.proto");
+
+#undef PATH_SEPARATOR
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, NonRootMapping) {
+  // Test setting up a search path mapping a directory to a non-root location.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=bar=$tmpdir bar/foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleGenerators) {
+  // Test that we can have multiple generators and use both in one invocation,
+  // each with a different output directory.
+
+  RegisterGenerator("test_generator_1", "--test1_out",
+                    "output1.test", "Test output 1.");
+  RegisterGenerator("test_generator_2", "--test2_out",
+                    "output2.test", "Test output 2.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  // Create the "a" and "b" sub-directories.
+  CreateTempFile("a/dummy", "");
+  CreateTempFile("b/dummy", "");
+
+  Run("protocol_compiler "
+      "--test1_out=$tmpdir/a "
+      "--test2_out=$tmpdir/b "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator_1", "", "foo.proto", "Foo", "a/output1.test");
+  ExpectGenerated("test_generator_2", "", "foo.proto", "Foo", "b/output2.test");
+}
+
+TEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) {
+  // Test that --disallow_services doesn't cause a problem when there are no
+  // services.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --disallow_services --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, DisallowServicesHasService) {
+  // Test that --disallow_services produces an error when there are services.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n"
+    "service Bar {}\n");
+
+  Run("protocol_compiler --disallow_services --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorSubstring("foo.proto: This file contains services");
+}
+
+TEST_F(CommandLineInterfaceTest, AllowServicesHasService) {
+  // Test that services work fine as long as --disallow_services is not used.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n"
+    "service Bar {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) {
+  // Test that we can accept working-directory-relative input files.
+
+  SetInputsAreProtoPathRelative(false);
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir $tmpdir/foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+}
+
+// -------------------------------------------------------------------
+
+TEST_F(CommandLineInterfaceTest, ParseErrors) {
+  // Test that parse errors are reported.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "badsyntax\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorText(
+    "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) {
+  // Test that parse errors are reported from multiple files.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  // We set up files such that foo.proto actually depends on bar.proto in
+  // two ways:  Directly and through baz.proto.  bar.proto's errors should
+  // only be reported once.
+  CreateTempFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "badsyntax\n");
+  CreateTempFile("baz.proto",
+    "syntax = \"proto2\";\n"
+    "import \"bar.proto\";\n");
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "import \"bar.proto\";\n"
+    "import \"baz.proto\";\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorText(
+    "bar.proto:2:1: Expected top-level statement (e.g. \"message\").\n"
+    "baz.proto: Import \"bar.proto\" was not found or had errors.\n"
+    "foo.proto: Import \"bar.proto\" was not found or had errors.\n"
+    "foo.proto: Import \"baz.proto\" was not found or had errors.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, InputNotFoundError) {
+  // Test what happens if the input file is not found.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorText(
+    "foo.proto: File not found.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) {
+  // Test what happens when a working-directory-relative input file is not
+  // found.
+
+  SetInputsAreProtoPathRelative(false);
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir $tmpdir/foo.proto");
+
+  ExpectErrorText(
+    "$tmpdir/foo.proto: No such file or directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) {
+  // Test what happens when a working-directory-relative input file is not
+  // mapped to a virtual path.
+
+  SetInputsAreProtoPathRelative(false);
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  // Create a directory called "bar" so that we can point --proto_path at it.
+  CreateTempFile("bar/dummy", "");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir/bar $tmpdir/foo.proto");
+
+  ExpectErrorText(
+    "$tmpdir/foo.proto: File does not reside within any path "
+      "specified using --proto_path (or -I).  You must specify a "
+      "--proto_path which encompasses this file.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) {
+  // Check what happens if the input file is not found *and* is not mapped
+  // in the proto_path.
+
+  SetInputsAreProtoPathRelative(false);
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  // Create a directory called "bar" so that we can point --proto_path at it.
+  CreateTempFile("bar/dummy", "");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir/bar $tmpdir/foo.proto");
+
+  ExpectErrorText(
+    "$tmpdir/foo.proto: No such file or directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) {
+  // Test what happens when a working-directory-relative input file is shadowed
+  // by another file in the virtual path.
+
+  SetInputsAreProtoPathRelative(false);
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo/foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempFile("bar/foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Bar {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir/foo --proto_path=$tmpdir/bar "
+      "$tmpdir/bar/foo.proto");
+
+  ExpectErrorText(
+    "$tmpdir/bar/foo.proto: Input is shadowed in the --proto_path "
+    "by \"$tmpdir/foo/foo.proto\".  Either use the latter "
+    "file as your input or reorder the --proto_path so that the "
+    "former file's location comes first.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) {
+  // Test what happens if the input file is not found.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir/foo foo.proto");
+
+  ExpectErrorText(
+    "$tmpdir/foo: warning: directory does not exist.\n"
+    "foo.proto: File not found.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingInputError) {
+  // Test that we get an error if no inputs are given.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir");
+
+  ExpectErrorText("Missing input file.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingOutputError) {
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --proto_path=$tmpdir foo.proto");
+
+  ExpectErrorText("Missing output directives.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputWriteError) {
+  MockCodeGenerator* generator =
+    RegisterGenerator("test_generator", "--test_out",
+                      "output.test", "Test output.");
+  generator->set_expect_write_error(true);
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  // Create a directory blocking our output location.
+  CreateTempFile("output.test.foo.proto/foo", "");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  // Windows with MSVCRT.dll produces EPERM instead of EISDIR.
+  if (HasAlternateErrorSubstring("output.test.foo.proto: Permission denied")) {
+    return;
+  }
+#endif
+
+  ExpectErrorSubstring("output.test.foo.proto: Is a directory");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) {
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir/nosuchdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorSubstring("nosuchdir/: "
+                       "No such file or directory");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) {
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir/foo.proto "
+      "--proto_path=$tmpdir foo.proto");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  // Windows with MSVCRT.dll produces EINVAL instead of ENOTDIR.
+  if (HasAlternateErrorSubstring("foo.proto/: Invalid argument")) {
+    return;
+  }
+#endif
+
+  ExpectErrorSubstring("foo.proto/: Not a directory");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorError) {
+  RegisterErrorGenerator("error_generator", "Test error message.",
+                         "--error_out", "output.test", "Test error output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --error_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorSubstring("--error_out: Test error message.");
+}
+
+TEST_F(CommandLineInterfaceTest, HelpText) {
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+  RegisterErrorGenerator("error_generator", "Test error message.",
+                         "--error_out", "output.test", "Test error output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("test_exec_name --help");
+
+  ExpectErrorSubstring("Usage: test_exec_name ");
+  ExpectErrorSubstring("--test_out=OUT_DIR");
+  ExpectErrorSubstring("Test output.");
+  ExpectErrorSubstring("--error_out=OUT_DIR");
+  ExpectErrorSubstring("Test error output.");
+}
+
+// -------------------------------------------------------------------
+// Flag parsing tests
+
+TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) {
+  // Test that a single-character flag works.
+
+  RegisterGenerator("test_generator", "-o",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler -o$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) {
+  // Test that separating the flag value with a space works.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --test_out $tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) {
+  // Test that separating the flag value with a space works for
+  // single-character flags.
+
+  RegisterGenerator("test_generator", "-o",
+                    "output.test", "Test output.");
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler -o $tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingValueError) {
+  // Test that we get an error if a flag is missing its value.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  Run("protocol_compiler --test_out --proto_path=$tmpdir foo.proto");
+
+  ExpectErrorText("Missing value for flag: --test_out\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) {
+  // Test that we get an error if the last argument is a flag requiring a
+  // value.
+
+  RegisterGenerator("test_generator", "--test_out",
+                    "output.test", "Test output.");
+
+  Run("protocol_compiler --test_out");
+
+  ExpectErrorText("Missing value for flag: --test_out\n");
+}
+
+}  // anonymous namespace
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
new file mode 100644
index 0000000..daa66c8
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -0,0 +1,135 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This test insures that google/protobuf/descriptor.pb.{h,cc} match exactly
+// what would be generated by the protocol compiler.  These files are not
+// generated automatically at build time because they are compiled into the
+// protocol compiler itself.  So, if they were auto-generated, you'd have a
+// chicken-and-egg problem.
+//
+// If this test fails, run the script
+// "generate_descriptor_proto.sh" and add
+// descriptor.pb.{h,cc} to your changelist.
+
+#include <map>
+
+#include <google/protobuf/compiler/cpp/cpp_generator.h>
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+class MockErrorCollector : public MultiFileErrorCollector {
+ public:
+  MockErrorCollector() {}
+  ~MockErrorCollector() {}
+
+  string text_;
+
+  // implements ErrorCollector ---------------------------------------
+  void AddError(const string& filename, int line, int column,
+                const string& message) {
+    strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n",
+                                 filename, line, column, message);
+  }
+};
+
+class MockOutputDirectory : public OutputDirectory {
+ public:
+  MockOutputDirectory() {}
+  ~MockOutputDirectory() {
+    STLDeleteValues(&files_);
+  }
+
+  void ExpectFileMatches(const string& virtual_filename,
+                         const string& physical_filename) {
+    string* expected_contents = FindPtrOrNull(files_, virtual_filename);
+    ASSERT_TRUE(expected_contents != NULL)
+      << "Generator failed to generate file: " << virtual_filename;
+
+    string actual_contents;
+    File::ReadFileToStringOrDie(
+      TestSourceDir() + "/" + physical_filename,
+      &actual_contents);
+    EXPECT_TRUE(actual_contents == *expected_contents)
+      << physical_filename << " needs to be regenerated.  Please run "
+         "generate_descriptor_proto.sh and add this file "
+         "to your CL.";
+  }
+
+  // implements OutputDirectory --------------------------------------
+
+  virtual io::ZeroCopyOutputStream* Open(const string& filename) {
+    string** map_slot = &files_[filename];
+    if (*map_slot != NULL) delete *map_slot;
+    *map_slot = new string;
+
+    return new io::StringOutputStream(*map_slot);
+  }
+
+ private:
+  map<string, string*> files_;
+};
+
+TEST(BootstrapTest, GeneratedDescriptorMatches) {
+  MockErrorCollector error_collector;
+  DiskSourceTree source_tree;
+  source_tree.MapPath("", TestSourceDir());
+  Importer importer(&source_tree, &error_collector);
+  const FileDescriptor* proto_file =
+    importer.Import("google/protobuf/descriptor.proto");
+  EXPECT_EQ("", error_collector.text_);
+  ASSERT_TRUE(proto_file != NULL);
+
+  CppGenerator generator;
+  MockOutputDirectory output_directory;
+  string error;
+  string parameter;
+  parameter = "dllexport_decl=LIBPROTOBUF_EXPORT";
+  ASSERT_TRUE(generator.Generate(proto_file, parameter,
+                                 &output_directory, &error));
+
+  output_directory.ExpectFileMatches("google/protobuf/descriptor.pb.h",
+                                     "google/protobuf/descriptor.pb.h");
+  output_directory.ExpectFileMatches("google/protobuf/descriptor.pb.cc",
+                                     "google/protobuf/descriptor.pb.cc");
+}
+
+}  // namespace
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc
new file mode 100644
index 0000000..f78d60d
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -0,0 +1,196 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <set>
+#include <map>
+
+#include <google/protobuf/compiler/cpp/cpp_enum.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
+                             const string& dllexport_decl)
+  : descriptor_(descriptor),
+    classname_(ClassName(descriptor, false)),
+    dllexport_decl_(dllexport_decl) {
+}
+
+EnumGenerator::~EnumGenerator() {}
+
+void EnumGenerator::GenerateDefinition(io::Printer* printer) {
+  map<string, string> vars;
+  vars["classname"] = classname_;
+  vars["short_name"] = descriptor_->name();
+
+  printer->Print(vars, "enum $classname$ {\n");
+  printer->Indent();
+
+  const EnumValueDescriptor* min_value = descriptor_->value(0);
+  const EnumValueDescriptor* max_value = descriptor_->value(0);
+
+  for (int i = 0; i < descriptor_->value_count(); i++) {
+    vars["name"] = descriptor_->value(i)->name();
+    vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+    vars["prefix"] = (descriptor_->containing_type() == NULL) ?
+      "" : classname_ + "_";
+
+    printer->Print(vars, "$prefix$$name$ = $number$,\n");
+
+    if (descriptor_->value(i)->number() < min_value->number()) {
+      min_value = descriptor_->value(i);
+    }
+    if (descriptor_->value(i)->number() > max_value->number()) {
+      max_value = descriptor_->value(i);
+    }
+  }
+
+  printer->Outdent();
+  printer->Print("};\n");
+
+  vars["min_name"] = min_value->name();
+  vars["max_name"] = max_value->name();
+
+  if (dllexport_decl_.empty()) {
+    vars["dllexport"] = "";
+  } else {
+    vars["dllexport"] = dllexport_decl_ + " ";
+  }
+
+  printer->Print(vars,
+    "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n"
+    "$dllexport$bool $classname$_IsValid(int value);\n"
+    "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n"
+    "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"
+    "\n");
+}
+
+void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
+  map<string, string> vars;
+  vars["nested_name"] = descriptor_->name();
+  vars["classname"] = classname_;
+  printer->Print(vars, "typedef $classname$ $nested_name$;\n");
+
+  for (int j = 0; j < descriptor_->value_count(); j++) {
+    vars["tag"] = descriptor_->value(j)->name();
+    printer->Print(vars,
+      "static const $nested_name$ $tag$ = $classname$_$tag$;\n");
+  }
+
+  printer->Print(vars,
+    "static inline const ::google::protobuf::EnumDescriptor*\n"
+    "$nested_name$_descriptor() {\n"
+    "  return $classname$_descriptor();\n"
+    "}\n"
+    "static inline bool $nested_name$_IsValid(int value) {\n"
+    "  return $classname$_IsValid(value);\n"
+    "}\n"
+    "static const $nested_name$ $nested_name$_MIN =\n"
+    "  $classname$_$nested_name$_MIN;\n"
+    "static const $nested_name$ $nested_name$_MAX =\n"
+    "  $classname$_$nested_name$_MAX;\n");
+}
+
+void EnumGenerator::GenerateDescriptorInitializer(
+    io::Printer* printer, int index) {
+  map<string, string> vars;
+  vars["classname"] = classname_;
+  vars["index"] = SimpleItoa(index);
+
+  if (descriptor_->containing_type() == NULL) {
+    printer->Print(vars,
+      "$classname$_descriptor_ = file->enum_type($index$);\n");
+  } else {
+    vars["parent"] = ClassName(descriptor_->containing_type(), false);
+    printer->Print(vars,
+      "$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n");
+  }
+}
+
+void EnumGenerator::GenerateMethods(io::Printer* printer) {
+  map<string, string> vars;
+  vars["classname"] = classname_;
+  vars["builddescriptorsname"] =
+      GlobalBuildDescriptorsName(descriptor_->file()->name());
+
+  printer->Print(vars,
+    "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
+    "  if ($classname$_descriptor_ == NULL) $builddescriptorsname$();\n"
+    "  return $classname$_descriptor_;\n"
+    "}\n"
+    "bool $classname$_IsValid(int value) {\n"
+    "  switch(value) {\n");
+
+  // Multiple values may have the same number.  Make sure we only cover
+  // each number once by first constructing a set containing all valid
+  // numbers, then printing a case statement for each element.
+
+  set<int> numbers;
+  for (int j = 0; j < descriptor_->value_count(); j++) {
+    const EnumValueDescriptor* value = descriptor_->value(j);
+    numbers.insert(value->number());
+  }
+
+  for (set<int>::iterator iter = numbers.begin();
+       iter != numbers.end(); ++iter) {
+    printer->Print(
+      "    case $number$:\n",
+      "number", SimpleItoa(*iter));
+  }
+
+  printer->Print(vars,
+    "      return true;\n"
+    "    default:\n"
+    "      return false;\n"
+    "  }\n"
+    "}\n"
+    "\n");
+
+  if (descriptor_->containing_type() != NULL) {
+    // We need to "define" the static constants which were declared in the
+    // header, to give the linker a place to put them.  Or at least the C++
+    // standard says we have to.  MSVC actually insists tha we do _not_ define
+    // them again in the .cc file.
+    printer->Print("#ifndef _MSC_VER\n");
+
+    vars["parent"] = ClassName(descriptor_->containing_type(), false);
+    vars["nested_name"] = descriptor_->name();
+    for (int i = 0; i < descriptor_->value_count(); i++) {
+      vars["value"] = descriptor_->value(i)->name();
+      printer->Print(vars,
+        "const $classname$ $parent$::$value$;\n");
+    }
+    printer->Print(vars,
+      "const $classname$ $parent$::$nested_name$_MIN;\n"
+      "const $classname$ $parent$::$nested_name$_MAX;\n");
+
+    printer->Print("#endif  // _MSC_VER\n");
+  }
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h
new file mode 100644
index 0000000..b30997c
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -0,0 +1,81 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+
+#include <string>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator {
+ public:
+  // See generator.cc for the meaning of dllexport_decl.
+  explicit EnumGenerator(const EnumDescriptor* descriptor,
+                         const string& dllexport_decl);
+  ~EnumGenerator();
+
+  // Header stuff.
+
+  // Generate header code defining the enum.  This code should be placed
+  // within the enum's package namespace, but NOT within any class, even for
+  // nested enums.
+  void GenerateDefinition(io::Printer* printer);
+
+  // For enums nested within a message, generate code to import all the enum's
+  // symbols (e.g. the enum type name, all its values, etc.) into the class's
+  // namespace.  This should be placed inside the class definition in the
+  // header.
+  void GenerateSymbolImports(io::Printer* printer);
+
+  // Source file stuff.
+
+  // Generate code that initializes the global variable storing the enum's
+  // descriptor.
+  void GenerateDescriptorInitializer(io::Printer* printer, int index);
+
+  // Generate non-inline methods related to the enum, such as IsValidValue().
+  // Goes in the .cc file.
+  void GenerateMethods(io::Printer* printer);
+
+ private:
+  const EnumDescriptor* descriptor_;
+  string classname_;
+  string dllexport_decl_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
new file mode 100644
index 0000000..e02d7d8
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -0,0 +1,226 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format_inl.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+
+namespace {
+
+// TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
+//   repeat code between this and the other field types.
+void SetEnumVariables(const FieldDescriptor* descriptor,
+                      map<string, string>* variables) {
+  const EnumValueDescriptor* default_value = descriptor->default_value_enum();
+
+  (*variables)["name"] = FieldName(descriptor);
+  (*variables)["type"] = ClassName(descriptor->enum_type(), true);
+  (*variables)["default"] = SimpleItoa(default_value->number());
+  (*variables)["index"] = SimpleItoa(descriptor->index());
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
+  (*variables)["tag_size"] = SimpleItoa(
+    WireFormat::TagSize(descriptor->number(), descriptor->type()));
+}
+
+}  // namespace
+
+// ===================================================================
+
+EnumFieldGenerator::
+EnumFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetEnumVariables(descriptor, &variables_);
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {}
+
+void EnumFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_, "int $name$_;\n");
+}
+
+void EnumFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $name$() const;\n"
+    "inline void set_$name$($type$ value);\n");
+}
+
+void EnumFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $classname$::$name$() const {\n"
+    "  return static_cast< $type$ >($name$_);\n"
+    "}\n"
+    "inline void $classname$::set_$name$($type$ value) {\n"
+    "  GOOGLE_DCHECK($type$_IsValid(value));\n"
+    "  _set_bit($index$);\n"
+    "  $name$_ = value;\n"
+    "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_, "set_$name$(from.$name$());\n");
+}
+
+void EnumFieldGenerator::
+GenerateInitializer(io::Printer* printer) const {
+  printer->Print(variables_, ",\n$name$_($default$)");
+}
+
+void EnumFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "int value;\n"
+    "DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));\n"
+    "if ($type$_IsValid(value)) {\n"
+    "  set_$name$(static_cast< $type$ >(value));\n"
+    "} else {\n"
+    "  mutable_unknown_fields()->AddField($number$)->add_varint(value);\n"
+    "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::WriteEnum("
+      "$number$, this->$name$(), output));\n");
+}
+
+void EnumFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ +\n"
+    "  ::google::protobuf::internal::WireFormat::EnumSize(this->$name$());\n");
+}
+
+// ===================================================================
+
+RepeatedEnumFieldGenerator::
+RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetEnumVariables(descriptor, &variables_);
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+void RepeatedEnumFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_, "::google::protobuf::RepeatedField<int> $name$_;\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedField<int>& $name$() const;\n"
+    "inline ::google::protobuf::RepeatedField<int>* mutable_$name$();\n"
+    "inline $type$ $name$(int index) const;\n"
+    "inline void set_$name$(int index, $type$ value);\n"
+    "inline void add_$name$($type$ value);\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedField<int>&\n"
+    "$classname$::$name$() const {\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline ::google::protobuf::RepeatedField<int>*\n"
+    "$classname$::mutable_$name$() {\n"
+    "  return &$name$_;\n"
+    "}\n"
+    "inline $type$ $classname$::$name$(int index) const {\n"
+    "  return static_cast< $type$ >($name$_.Get(index));\n"
+    "}\n"
+    "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+    "  GOOGLE_DCHECK($type$_IsValid(value));\n"
+    "  $name$_.Set(index, value);\n"
+    "}\n"
+    "inline void $classname$::add_$name$($type$ value) {\n"
+    "  GOOGLE_DCHECK($type$_IsValid(value));\n"
+    "  $name$_.Add(value);\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateInitializer(io::Printer* printer) const {
+  // Not needed for repeated fields.
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "int value;\n"
+    "DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));\n"
+    "if ($type$_IsValid(value)) {\n"
+    "  add_$name$(static_cast< $type$ >(value));\n"
+    "} else {\n"
+    "  mutable_unknown_fields()->AddField($number$)->add_varint(value);\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::WriteEnum("
+      "$number$, this->$name$(i), output));\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ * $name$_size();\n"
+    "for (int i = 0; i < $name$_size(); i++) {\n"
+    "  total_size += ::google::protobuf::internal::WireFormat::EnumSize(\n"
+    "    this->$name$(i));\n"
+    "}\n");
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
new file mode 100644
index 0000000..a297e96
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumFieldGenerator : public FieldGenerator {
+ public:
+  explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
+  ~EnumFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GeneratePrivateMembers(io::Printer* printer) const;
+  void GenerateAccessorDeclarations(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateInitializer(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
+};
+
+class RepeatedEnumFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor);
+  ~RepeatedEnumFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GeneratePrivateMembers(io::Printer* printer) const;
+  void GenerateAccessorDeclarations(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateInitializer(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc
new file mode 100644
index 0000000..87da63d
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -0,0 +1,104 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_extension.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
+                                       const string& dllexport_decl)
+  : descriptor_(descriptor),
+    dllexport_decl_(dllexport_decl) {
+  // Construct type_traits_.
+  if (descriptor_->is_repeated()) {
+    type_traits_ = "Repeated";
+  }
+
+  switch (descriptor_->cpp_type()) {
+    case FieldDescriptor::CPPTYPE_ENUM:
+      type_traits_.append("EnumTypeTraits< ");
+      type_traits_.append(ClassName(descriptor_->enum_type(), true));
+      type_traits_.append(" >");
+      break;
+    case FieldDescriptor::CPPTYPE_STRING:
+      type_traits_.append("StringTypeTraits");
+      break;
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      type_traits_.append("MessageTypeTraits< ");
+      type_traits_.append(ClassName(descriptor_->message_type(), true));
+      type_traits_.append(" >");
+      break;
+    default:
+      type_traits_.append("PrimitiveTypeTraits< ");
+      type_traits_.append(PrimitiveTypeName(descriptor_->cpp_type()));
+      type_traits_.append(" >");
+      break;
+  }
+}
+
+ExtensionGenerator::~ExtensionGenerator() {}
+
+void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
+  map<string, string> vars;
+  vars["extendee"   ] = ClassName(descriptor_->containing_type(), true);
+  vars["type_traits"] = type_traits_;
+  vars["name"       ] = descriptor_->name();
+
+  // If this is a class member, it needs to be declared "static".  Otherwise,
+  // it needs to be "extern".
+  vars["qualifier"] =
+    (descriptor_->extension_scope() == NULL) ? "extern" : "static";
+
+  if (!dllexport_decl_.empty()) {
+    vars["qualifier"] = dllexport_decl_ + " " + vars["qualifier"];
+  }
+
+  printer->Print(vars,
+    "$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
+    "  ::google::protobuf::internal::$type_traits$ > $name$;\n");
+}
+
+void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
+  map<string, string> vars;
+  vars["extendee"   ] = ClassName(descriptor_->containing_type(), true);
+  vars["number"     ] = SimpleItoa(descriptor_->number());
+  vars["type_traits"] = type_traits_;
+  vars["name"       ] = descriptor_->name();
+
+  // If this is a class member, it needs to be declared in its class scope.
+  vars["scope"] = (descriptor_->extension_scope() == NULL) ? "" :
+    ClassName(descriptor_->extension_scope(), false) + "::";
+
+  printer->Print(vars,
+    "::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
+    "  ::google::protobuf::internal::$type_traits$ > $scope$$name$($number$);\n");
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.h b/src/google/protobuf/compiler/cpp/cpp_extension.h
new file mode 100644
index 0000000..149dbca
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_extension.h
@@ -0,0 +1,68 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+  class FieldDescriptor;       // descriptor.h
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Generates code for an extension, which may be within the scope of some
+// message or may be at file scope.  This is much simpler than FieldGenerator
+// since extensions are just simple identifiers with interesting types.
+class ExtensionGenerator {
+ public:
+  // See generator.cc for the meaning of dllexport_decl.
+  explicit ExtensionGenerator(const FieldDescriptor* descriptor,
+                              const string& dllexport_decl);
+  ~ExtensionGenerator();
+
+  // Header stuff.
+  void GenerateDeclaration(io::Printer* printer);
+
+  // Source file stuff.
+  void GenerateDefinition(io::Printer* printer);
+
+ private:
+  const FieldDescriptor* descriptor_;
+  string type_traits_;
+  string dllexport_decl_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc
new file mode 100644
index 0000000..2b1041b
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -0,0 +1,83 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
+#include <google/protobuf/compiler/cpp/cpp_string_field.h>
+#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
+#include <google/protobuf/compiler/cpp/cpp_message_field.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+FieldGenerator::~FieldGenerator() {}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
+  : descriptor_(descriptor),
+    field_generators_(
+      new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
+  // Construct all the FieldGenerators.
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    field_generators_[i].reset(MakeGenerator(descriptor->field(i)));
+  }
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
+  if (field->is_repeated()) {
+    switch (field->cpp_type()) {
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        return new RepeatedMessageFieldGenerator(field);
+      case FieldDescriptor::CPPTYPE_STRING:
+          return new RepeatedStringFieldGenerator(field);
+      case FieldDescriptor::CPPTYPE_ENUM:
+        return new RepeatedEnumFieldGenerator(field);
+      default:
+        return new RepeatedPrimitiveFieldGenerator(field);
+    }
+  } else {
+    switch (field->cpp_type()) {
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        return new MessageFieldGenerator(field);
+      case FieldDescriptor::CPPTYPE_STRING:
+          return new StringFieldGenerator(field);
+      case FieldDescriptor::CPPTYPE_ENUM:
+        return new EnumFieldGenerator(field);
+      default:
+        return new PrimitiveFieldGenerator(field);
+    }
+  }
+}
+
+FieldGeneratorMap::~FieldGeneratorMap() {}
+
+const FieldGenerator& FieldGeneratorMap::get(
+    const FieldDescriptor* field) const {
+  GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+  return *field_generators_[field->index()];
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h
new file mode 100644
index 0000000..d37eb96
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -0,0 +1,127 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class FieldGenerator {
+ public:
+  FieldGenerator() {}
+  virtual ~FieldGenerator();
+
+  // Generate lines of code declaring members fields of the message class
+  // needed to represent this field.  These are placed inside the message
+  // class.
+  virtual void GeneratePrivateMembers(io::Printer* printer) const = 0;
+
+  // Generate prototypes for all of the accessor functions related to this
+  // field.  These are placed inside the class definition.
+  virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0;
+
+  // Generate inline definitions of accessor functions for this field.
+  // These are placed inside the header after all class definitions.
+  virtual void GenerateInlineAccessorDefinitions(
+    io::Printer* printer) const = 0;
+
+  // Generate definitions of accessors that aren't inlined.  These are
+  // placed somewhere in the .cc file.
+  // Most field types don't need this, so the default implementation is empty.
+  virtual void GenerateNonInlineAccessorDefinitions(
+    io::Printer* printer) const {}
+
+  // Generate lines of code (statements, not declarations) which clear the
+  // field.  This is used to define the clear_$name$() method as well as
+  // the Clear() method for the whole message.
+  virtual void GenerateClearingCode(io::Printer* printer) const = 0;
+
+  // Generate lines of code (statements, not declarations) which merges the
+  // contents of the field from the current message to the target message,
+  // which is stored in the generated code variable "from".
+  // This is used to fill in the MergeFrom method for the whole message.
+  // Details of this usage can be found in message.cc under the
+  // GenerateMergeFrom method.
+  virtual void GenerateMergingCode(io::Printer* printer) const = 0;
+
+  // Generate any initializers needed for the private members declared by
+  // GeneratePrivateMembers().  These go into the message class's
+  // constructor's initializer list.  For each initializer, this method
+  // must print the comma and newline separating it from the *previous*
+  // initializer, not the *next* initailizer.  That is, print a ",\n" first,
+  // e.g.:
+  //   printer->Print(",\n$name$_($default$)");
+  virtual void GenerateInitializer(io::Printer* printer) const = 0;
+
+  // Generate any code that needs to go in the class's destructor.
+  // Most field types don't need this, so the default implementation is empty.
+  virtual void GenerateDestructorCode(io::Printer* printer) const {}
+
+  // Generate lines to decode this field, which will be placed inside the
+  // message's MergeFromCodedStream() method.
+  virtual void GenerateMergeFromCodedStream(io::Printer* printer) const = 0;
+
+  // Generate lines to serialize this field, which are placed within the
+  // message's SerializeWithCachedSizes() method.
+  virtual void GenerateSerializeWithCachedSizes(io::Printer* printer) const = 0;
+
+  // Generate lines to compute the serialized size of this field, which
+  // are placed in the message's ByteSize() method.
+  virtual void GenerateByteSize(io::Printer* printer) const = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
+};
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+class FieldGeneratorMap {
+ public:
+  explicit FieldGeneratorMap(const Descriptor* descriptor);
+  ~FieldGeneratorMap();
+
+  const FieldGenerator& get(const FieldDescriptor* field) const;
+
+ private:
+  const Descriptor* descriptor_;
+  scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
+
+  static FieldGenerator* MakeGenerator(const FieldDescriptor* field);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
new file mode 100644
index 0000000..aea3a4b
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -0,0 +1,404 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_file.h>
+#include <google/protobuf/compiler/cpp/cpp_enum.h>
+#include <google/protobuf/compiler/cpp/cpp_service.h>
+#include <google/protobuf/compiler/cpp/cpp_extension.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/compiler/cpp/cpp_message.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// ===================================================================
+
+FileGenerator::FileGenerator(const FileDescriptor* file,
+                             const string& dllexport_decl)
+  : file_(file),
+    message_generators_(
+      new scoped_ptr<MessageGenerator>[file->message_type_count()]),
+    enum_generators_(
+      new scoped_ptr<EnumGenerator>[file->enum_type_count()]),
+    service_generators_(
+      new scoped_ptr<ServiceGenerator>[file->service_count()]),
+    extension_generators_(
+      new scoped_ptr<ExtensionGenerator>[file->extension_count()]) {
+
+  for (int i = 0; i < file->message_type_count(); i++) {
+    message_generators_[i].reset(
+      new MessageGenerator(file->message_type(i), dllexport_decl));
+  }
+
+  for (int i = 0; i < file->enum_type_count(); i++) {
+    enum_generators_[i].reset(
+      new EnumGenerator(file->enum_type(i), dllexport_decl));
+  }
+
+  for (int i = 0; i < file->service_count(); i++) {
+    service_generators_[i].reset(
+      new ServiceGenerator(file->service(i), dllexport_decl));
+  }
+
+  for (int i = 0; i < file->extension_count(); i++) {
+    extension_generators_[i].reset(
+      new ExtensionGenerator(file->extension(i), dllexport_decl));
+  }
+
+  SplitStringUsing(file_->package(), ".", &package_parts_);
+}
+
+FileGenerator::~FileGenerator() {}
+
+void FileGenerator::GenerateHeader(io::Printer* printer) {
+  string filename_identifier = FilenameIdentifier(file_->name());
+
+  // Generate top of header.
+  printer->Print(
+    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
+    "\n"
+    "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
+    "#define PROTOBUF_$filename_identifier$__INCLUDED\n"
+    "\n"
+    "#include <string>\n"
+    "\n",
+    "filename_identifier", filename_identifier);
+
+  printer->Print(
+    "#include <google/protobuf/stubs/common.h>\n"
+    "\n");
+
+  // Verify the protobuf library header version is compatible with the protoc
+  // version before going any further.
+  printer->Print(
+    "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n"
+    "#error This file was generated by a newer version of protoc which is\n"
+    "#error incompatible with your Protocol Buffer headers.  Please update\n"
+    "#error your headers.\n"
+    "#endif\n"
+    "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
+    "#error This file was generated by an older version of protoc which is\n"
+    "#error incompatible with your Protocol Buffer headers.  Please\n"
+    "#error regenerate this file with a newer version of protoc.\n"
+    "#endif\n"
+    "\n",
+    "min_header_version",
+      SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc),
+    "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION));
+
+  // OK, it's now safe to #include other files.
+  printer->Print(
+    "#include <google/protobuf/generated_message_reflection.h>\n"
+    "#include <google/protobuf/repeated_field.h>\n"
+    "#include <google/protobuf/extension_set.h>\n");
+
+  if (file_->service_count() > 0) {
+    printer->Print(
+      "#include <google/protobuf/service.h>\n");
+  }
+
+  for (int i = 0; i < file_->dependency_count(); i++) {
+    printer->Print(
+      "#include \"$dependency$.pb.h\"\n",
+      "dependency", StripProto(file_->dependency(i)->name()));
+  }
+
+  // Open namespace.
+  GenerateNamespaceOpeners(printer);
+
+  printer->Print("\n");
+
+  // Generate forward declarations of classes.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateForwardDeclaration(printer);
+  }
+
+  printer->Print("\n");
+
+  // Generate enum definitions.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateEnumDefinitions(printer);
+  }
+  for (int i = 0; i < file_->enum_type_count(); i++) {
+    enum_generators_[i]->GenerateDefinition(printer);
+  }
+
+  printer->Print(kThickSeparator);
+  printer->Print("\n");
+
+  // Generate class definitions.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    if (i > 0) {
+      printer->Print("\n");
+      printer->Print(kThinSeparator);
+      printer->Print("\n");
+    }
+    message_generators_[i]->GenerateClassDefinition(printer);
+  }
+
+  printer->Print("\n");
+  printer->Print(kThickSeparator);
+  printer->Print("\n");
+
+  // Generate service definitions.
+  for (int i = 0; i < file_->service_count(); i++) {
+    if (i > 0) {
+      printer->Print("\n");
+      printer->Print(kThinSeparator);
+      printer->Print("\n");
+    }
+    service_generators_[i]->GenerateDeclarations(printer);
+  }
+
+  printer->Print("\n");
+  printer->Print(kThickSeparator);
+  printer->Print("\n");
+
+  // Declare extension identifiers.
+  for (int i = 0; i < file_->extension_count(); i++) {
+    extension_generators_[i]->GenerateDeclaration(printer);
+  }
+
+  printer->Print("\n");
+  printer->Print(kThickSeparator);
+  printer->Print("\n");
+
+  // Generate class inline methods.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    if (i > 0) {
+      printer->Print(kThinSeparator);
+      printer->Print("\n");
+    }
+    message_generators_[i]->GenerateInlineMethods(printer);
+  }
+
+  // Close up namespace.
+  GenerateNamespaceClosers(printer);
+
+  printer->Print(
+    "#endif  // PROTOBUF_$filename_identifier$__INCLUDED\n",
+    "filename_identifier", filename_identifier);
+}
+
+void FileGenerator::GenerateSource(io::Printer* printer) {
+  printer->Print(
+    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
+    "\n"
+    "#include \"$basename$.pb.h\"\n"
+    "#include <google/protobuf/descriptor.h>\n"
+    "#include <google/protobuf/io/coded_stream.h>\n"
+    "#include <google/protobuf/reflection_ops.h>\n"
+    "#include <google/protobuf/wire_format_inl.h>\n",
+    "basename", StripProto(file_->name()));
+
+  // For each dependency, write a prototype for that dependency's
+  // BuildDescriptors() function.  We don't expose these in the header because
+  // they are internal implementation details, and since this is generated code
+  // we don't have the usual risks involved with declaring external functions
+  // within a .cc file.
+  for (int i = 0; i < file_->dependency_count(); i++) {
+    const FileDescriptor* dependency = file_->dependency(i);
+    // Open the dependency's namespace.
+    vector<string> dependency_package_parts;
+    SplitStringUsing(dependency->package(), ".", &dependency_package_parts);
+    for (int i = 0; i < dependency_package_parts.size(); i++) {
+      printer->Print("namespace $name$ { ",
+                     "name", dependency_package_parts[i]);
+    }
+    // Declare its BuildDescriptors() function.
+    printer->Print(
+      "void $function$();",
+      "function", GlobalBuildDescriptorsName(dependency->name()));
+    // Close the namespace.
+    for (int i = 0; i < dependency_package_parts.size(); i++) {
+      printer->Print(" }");
+    }
+    printer->Print("\n");
+  }
+
+  GenerateNamespaceOpeners(printer);
+
+  printer->Print(
+    "\n"
+    "namespace {\n"
+    "\n");
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateDescriptorDeclarations(printer);
+  }
+  for (int i = 0; i < file_->enum_type_count(); i++) {
+    printer->Print(
+      "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
+      "name", ClassName(file_->enum_type(i), false));
+  }
+  for (int i = 0; i < file_->service_count(); i++) {
+    printer->Print(
+      "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
+      "name", file_->service(i)->name());
+  }
+
+  printer->Print(
+    "\n"
+    "}  // namespace\n"
+    "\n");
+
+  // Define our externally-visible BuildDescriptors() function.
+  GenerateBuildDescriptors(printer);
+
+  // Generate enums.
+  for (int i = 0; i < file_->enum_type_count(); i++) {
+    enum_generators_[i]->GenerateMethods(printer);
+  }
+
+  // Generate classes.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    printer->Print("\n");
+    printer->Print(kThickSeparator);
+    printer->Print("\n");
+    message_generators_[i]->GenerateClassMethods(printer);
+  }
+
+  // Generate services.
+  for (int i = 0; i < file_->service_count(); i++) {
+    if (i == 0) printer->Print("\n");
+    printer->Print(kThickSeparator);
+    printer->Print("\n");
+    service_generators_[i]->GenerateImplementation(printer);
+  }
+
+  // Define extensions.
+  for (int i = 0; i < file_->extension_count(); i++) {
+    extension_generators_[i]->GenerateDefinition(printer);
+  }
+
+  GenerateNamespaceClosers(printer);
+}
+
+void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
+  // BuildDescriptors() is a file-level procedure which initializes all of
+  // the Descriptor objects for this file.  It runs the first time one of the
+  // descriptors is accessed.  This will always be at static initialization
+  // 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.
+  printer->Print(
+    "\n"
+    "void $builddescriptorsname$() {\n"
+    "  static bool already_here = false;\n"
+    "  if (already_here) return;\n"
+    "  already_here = true;\n"
+    "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
+    "  ::google::protobuf::DescriptorPool* pool =\n"
+    "    ::google::protobuf::DescriptorPool::internal_generated_pool();\n"
+    "\n",
+    "builddescriptorsname", GlobalBuildDescriptorsName(file_->name()));
+  printer->Indent();
+
+  // Call the BuildDescriptors() methods for all of our dependencies, to make
+  // sure they get initialized first.
+  for (int i = 0; i < file_->dependency_count(); i++) {
+    const FileDescriptor* dependency = file_->dependency(i);
+    // Print the namespace prefix for the dependency.
+    vector<string> dependency_package_parts;
+    SplitStringUsing(dependency->package(), ".", &dependency_package_parts);
+    printer->Print("::");
+    for (int i = 0; i < dependency_package_parts.size(); i++) {
+      printer->Print("$name$::",
+                     "name", dependency_package_parts[i]);
+    }
+    // Call its BuildDescriptors function.
+    printer->Print(
+      "$name$();\n",
+      "name", GlobalBuildDescriptorsName(dependency->name()));
+  }
+
+  // Embed the descriptor.  We simply serialize the entire FileDescriptorProto
+  // and embed it as a string literal, which is parsed and built into real
+  // descriptors at initialization time.
+  FileDescriptorProto file_proto;
+  file_->CopyTo(&file_proto);
+  string file_data;
+  file_proto.SerializeToString(&file_data);
+
+  printer->Print(
+    "const ::google::protobuf::FileDescriptor* file = pool->InternalBuildGeneratedFile(");
+
+  // Only write 40 bytes per line.
+  static const int kBytesPerLine = 40;
+  for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+    printer->Print("\n  \"$data$\"",
+      "data", CEscape(file_data.substr(i, kBytesPerLine)));
+  }
+  printer->Print(
+    ", $size$);\n",
+    "size", SimpleItoa(file_data.size()));
+
+  // Assign all global descriptors.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateDescriptorInitializer(printer, i);
+  }
+  for (int i = 0; i < file_->enum_type_count(); i++) {
+    enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
+  }
+  for (int i = 0; i < file_->service_count(); i++) {
+    service_generators_[i]->GenerateDescriptorInitializer(printer, i);
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "\n"
+    "// Force BuildDescriptors() to be called at static initialization time.\n"
+    "struct StaticDescriptorInitializer_$filename$ {\n"
+    "  StaticDescriptorInitializer_$filename$() {\n"
+    "    $builddescriptorsname$();\n"
+    "  }\n"
+    "} static_descriptor_initializer_$filename$_;\n"
+    "\n",
+    "builddescriptorsname", GlobalBuildDescriptorsName(file_->name()),
+    "filename", FilenameIdentifier(file_->name()));
+}
+
+void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) {
+  if (package_parts_.size() > 0) printer->Print("\n");
+
+  for (int i = 0; i < package_parts_.size(); i++) {
+    printer->Print("namespace $part$ {\n",
+                   "part", package_parts_[i]);
+  }
+}
+
+void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) {
+  if (package_parts_.size() > 0) printer->Print("\n");
+
+  for (int i = package_parts_.size() - 1; i >= 0; i--) {
+    printer->Print("}  // namespace $part$\n",
+                   "part", package_parts_[i]);
+  }
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h
new file mode 100644
index 0000000..f2255ee
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -0,0 +1,82 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+  class FileDescriptor;        // descriptor.h
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator;           // enum.h
+class MessageGenerator;        // message.h
+class ServiceGenerator;        // service.h
+class ExtensionGenerator;      // extension.h
+
+class FileGenerator {
+ public:
+  // See generator.cc for the meaning of dllexport_decl.
+  explicit FileGenerator(const FileDescriptor* file,
+                         const string& dllexport_decl);
+  ~FileGenerator();
+
+  void GenerateHeader(io::Printer* printer);
+  void GenerateSource(io::Printer* printer);
+
+ private:
+  // Generate the BuildDescriptors() procedure, which builds all descriptors
+  // for types defined in the file.
+  void GenerateBuildDescriptors(io::Printer* printer);
+
+  void GenerateNamespaceOpeners(io::Printer* printer);
+  void GenerateNamespaceClosers(io::Printer* printer);
+
+  const FileDescriptor* file_;
+
+  scoped_array<scoped_ptr<MessageGenerator> > message_generators_;
+  scoped_array<scoped_ptr<EnumGenerator> > enum_generators_;
+  scoped_array<scoped_ptr<ServiceGenerator> > service_generators_;
+  scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
+
+  // E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
+  vector<string> package_parts_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc
new file mode 100644
index 0000000..200f635
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -0,0 +1,135 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_generator.h>
+
+#include <vector>
+#include <utility>
+
+#include <google/protobuf/compiler/cpp/cpp_file.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+// Parses a set of comma-delimited name/value pairs, e.g.:
+//   "foo=bar,baz,qux=corge"
+// parses to the pairs:
+//   ("foo", "bar"), ("baz", ""), ("qux", "corge")
+void ParseOptions(const string& text, vector<pair<string, string> >* output) {
+  vector<string> parts;
+  SplitStringUsing(text, ",", &parts);
+
+  for (int i = 0; i < parts.size(); i++) {
+    string::size_type equals_pos = parts[i].find_first_of('=');
+    pair<string, string> value;
+    if (equals_pos == string::npos) {
+      value.first = parts[i];
+      value.second = "";
+    } else {
+      value.first = parts[i].substr(0, equals_pos);
+      value.second = parts[i].substr(equals_pos + 1);
+    }
+    output->push_back(value);
+  }
+}
+
+}  // namespace
+
+CppGenerator::CppGenerator() {}
+CppGenerator::~CppGenerator() {}
+
+bool CppGenerator::Generate(const FileDescriptor* file,
+                            const string& parameter,
+                            OutputDirectory* output_directory,
+                            string* error) const {
+  vector<pair<string, string> > options;
+  ParseOptions(parameter, &options);
+
+  // -----------------------------------------------------------------
+  // parse generator options
+
+  // TODO(kenton):  If we ever have more options, we may want to create a
+  //   class that encapsulates them which we can pass down to all the
+  //   generator classes.  Currently we pass dllexport_decl down to all of
+  //   them via the constructors, but we don't want to have to add another
+  //   constructor parameter for every option.
+
+  // If the dllexport_decl option is passed to the compiler, we need to write
+  // it in front of every symbol that should be exported if this .proto is
+  // compiled into a Windows DLL.  E.g., if the user invokes the protocol
+  // compiler as:
+  //   protoc --cpp_out=dllexport_decl=FOO_EXPORT:outdir foo.proto
+  // then we'll define classes like this:
+  //   class FOO_EXPORT Foo {
+  //     ...
+  //   }
+  // FOO_EXPORT is a macro which should expand to __declspec(dllexport) or
+  // __declspec(dllimport) depending on what is being compiled.
+  string dllexport_decl;
+
+  for (int i = 0; i < options.size(); i++) {
+    if (options[i].first == "dllexport_decl") {
+      dllexport_decl = options[i].second;
+    } else {
+      *error = "Unknown generator option: " + options[i].first;
+      return false;
+    }
+  }
+
+  // -----------------------------------------------------------------
+
+
+  string basename = StripProto(file->name());
+  basename.append(".pb");
+
+  FileGenerator file_generator(file, dllexport_decl);
+
+  // Generate header.
+  {
+    scoped_ptr<io::ZeroCopyOutputStream> output(
+      output_directory->Open(basename + ".h"));
+    io::Printer printer(output.get(), '$');
+    file_generator.GenerateHeader(&printer);
+  }
+
+  // Generate cc file.
+  {
+    scoped_ptr<io::ZeroCopyOutputStream> output(
+      output_directory->Open(basename + ".cc"));
+    io::Printer printer(output.get(), '$');
+    file_generator.GenerateSource(&printer);
+  }
+
+  return true;
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.h b/src/google/protobuf/compiler/cpp/cpp_generator.h
new file mode 100644
index 0000000..26fb8e9
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.h
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Generates C++ code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
+
+#include <string>
+#include <google/protobuf/compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// CodeGenerator implementation which generates a C++ source file and
+// header.  If you create your own protocol compiler binary and you want
+// it to support C++ output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator {
+ public:
+  CppGenerator();
+  ~CppGenerator();
+
+  // implements CodeGenerator ----------------------------------------
+  bool Generate(const FileDescriptor* file,
+                const string& parameter,
+                OutputDirectory* output_directory,
+                string* error) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
new file mode 100644
index 0000000..21de816
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -0,0 +1,197 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <vector>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+string DotsToUnderscores(const string& name) {
+  return StringReplace(name, ".", "_", true);
+}
+
+string DotsToColons(const string& name) {
+  return StringReplace(name, ".", "::", true);
+}
+
+const char* const kKeywordList[] = {
+  "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case",
+  "catch", "char", "class", "compl", "const", "const_cast", "continue",
+  "default", "delete", "do", "double", "dynamic_cast", "else", "enum",
+  "explicit", "extern", "false", "float", "for", "friend", "goto", "if",
+  "inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq",
+  "operator", "or", "or_eq", "private", "protected", "public", "register",
+  "reinterpret_cast", "return", "short", "signed", "sizeof", "static",
+  "static_cast", "struct", "switch", "template", "this", "throw", "true", "try",
+  "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual",
+  "void", "volatile", "wchar_t", "while", "xor", "xor_eq"
+};
+
+hash_set<string> MakeKeywordsMap() {
+  hash_set<string> result;
+  for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); i++) {
+    result.insert(kKeywordList[i]);
+  }
+  return result;
+}
+
+hash_set<string> kKeywords = MakeKeywordsMap();
+
+}  // namespace
+
+const char kThickSeparator[] =
+  "// ===================================================================\n";
+const char kThinSeparator[] =
+  "// -------------------------------------------------------------------\n";
+
+string ClassName(const Descriptor* descriptor, bool qualified) {
+  // Find "outer", the descriptor of the top-level message in which
+  // "descriptor" is embedded.
+  const Descriptor* outer = descriptor;
+  while (outer->containing_type() != NULL) outer = outer->containing_type();
+
+  const string& outer_name = outer->full_name();
+  string inner_name = descriptor->full_name().substr(outer_name.size());
+
+  if (qualified) {
+    return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name);
+  } else {
+    return outer->name() + DotsToUnderscores(inner_name);
+  }
+}
+
+string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) {
+  if (enum_descriptor->containing_type() == NULL) {
+    if (qualified) {
+      return DotsToColons(enum_descriptor->full_name());
+    } else {
+      return enum_descriptor->name();
+    }
+  } else {
+    string result = ClassName(enum_descriptor->containing_type(), qualified);
+    result += '_';
+    result += enum_descriptor->name();
+    return result;
+  }
+}
+
+string FieldName(const FieldDescriptor* field) {
+  string result = field->name();
+  LowerString(&result);
+  if (kKeywords.count(result) > 0) {
+    result.append("_");
+  }
+  return result;
+}
+
+string StripProto(const string& filename) {
+  if (HasSuffixString(filename, ".protodevel")) {
+    return StripSuffixString(filename, ".protodevel");
+  } else {
+    return StripSuffixString(filename, ".proto");
+  }
+}
+
+const char* PrimitiveTypeName(FieldDescriptor::CppType type) {
+  switch (type) {
+    case FieldDescriptor::CPPTYPE_INT32  : return "::google::protobuf::int32";
+    case FieldDescriptor::CPPTYPE_INT64  : return "::google::protobuf::int64";
+    case FieldDescriptor::CPPTYPE_UINT32 : return "::google::protobuf::uint32";
+    case FieldDescriptor::CPPTYPE_UINT64 : return "::google::protobuf::uint64";
+    case FieldDescriptor::CPPTYPE_DOUBLE : return "double";
+    case FieldDescriptor::CPPTYPE_FLOAT  : return "float";
+    case FieldDescriptor::CPPTYPE_BOOL   : return "bool";
+    case FieldDescriptor::CPPTYPE_ENUM   : return "int";
+    case FieldDescriptor::CPPTYPE_STRING : return "::std::string";
+    case FieldDescriptor::CPPTYPE_MESSAGE: return NULL;
+
+    // No default because we want the compiler to complain if any new
+    // CppTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return NULL;
+}
+
+const char* DeclaredTypeMethodName(FieldDescriptor::Type type) {
+  switch (type) {
+    case FieldDescriptor::TYPE_INT32   : return "Int32";
+    case FieldDescriptor::TYPE_INT64   : return "Int64";
+    case FieldDescriptor::TYPE_UINT32  : return "UInt32";
+    case FieldDescriptor::TYPE_UINT64  : return "UInt64";
+    case FieldDescriptor::TYPE_SINT32  : return "SInt32";
+    case FieldDescriptor::TYPE_SINT64  : return "SInt64";
+    case FieldDescriptor::TYPE_FIXED32 : return "Fixed32";
+    case FieldDescriptor::TYPE_FIXED64 : return "Fixed64";
+    case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
+    case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
+    case FieldDescriptor::TYPE_FLOAT   : return "Float";
+    case FieldDescriptor::TYPE_DOUBLE  : return "Double";
+
+    case FieldDescriptor::TYPE_BOOL    : return "Bool";
+    case FieldDescriptor::TYPE_ENUM    : return "Enum";
+
+    case FieldDescriptor::TYPE_STRING  : return "String";
+    case FieldDescriptor::TYPE_BYTES   : return "Bytes";
+    case FieldDescriptor::TYPE_GROUP   : return "Group";
+    case FieldDescriptor::TYPE_MESSAGE : return "Message";
+
+    // No default because we want the compiler to complain if any new
+    // types are added.
+  }
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return "";
+}
+
+// Convert a file name into a valid identifier.
+string FilenameIdentifier(const string& filename) {
+  string result;
+  for (int i = 0; i < filename.size(); i++) {
+    if (ascii_isalnum(filename[i])) {
+      result.push_back(filename[i]);
+    } else {
+      // Not alphanumeric.  To avoid any possibility of name conflicts we
+      // use the hex code for the character.
+      result.push_back('_');
+      char buffer[kFastToBufferSize];
+      result.append(FastHexToBuffer(static_cast<uint8>(filename[i]), buffer));
+    }
+  }
+  return result;
+}
+
+// Return the name of the BuildDescriptors() function for a given file.
+string GlobalBuildDescriptorsName(const string& filename) {
+  return "proto_BuildDescriptors_" + FilenameIdentifier(filename);
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
new file mode 100644
index 0000000..7f57d69
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -0,0 +1,86 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
+
+#include <string>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Commonly-used separator comments.  Thick is a line of '=', thin is a line
+// of '-'.
+extern const char kThickSeparator[];
+extern const char kThinSeparator[];
+
+// Returns the non-nested type name for the given type.  If "qualified" is
+// true, prefix the type with the full namespace.  For example, if you had:
+//   package foo.bar;
+//   message Baz { message Qux {} }
+// Then the qualified ClassName for Qux would be:
+//   ::foo::bar::Baz_Qux
+// While the non-qualified version would be:
+//   Baz_Qux
+string ClassName(const Descriptor* descriptor, bool qualified);
+string ClassName(const EnumDescriptor* enum_descriptor, bool qualified);
+
+// Get the (unqualified) name that should be used for this field in C++ code.
+// The name is coerced to lower-case to emulate proto1 behavior.  People
+// should be using lowercase-with-underscores style for proto field names
+// anyway, so normally this just returns field->name().
+string FieldName(const FieldDescriptor* field);
+
+// Returns the scope where the field was defined (for extensions, this is
+// different from the message type to which the field applies).
+inline const Descriptor* FieldScope(const FieldDescriptor* field) {
+  return field->is_extension() ?
+    field->extension_scope() : field->containing_type();
+}
+
+// Strips ".proto" or ".protodevel" from the end of a filename.
+string StripProto(const string& filename);
+
+// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
+// Note:  non-built-in type names will be qualified, meaning they will start
+// with a ::.  If you are using the type as a template parameter, you will
+// need to insure there is a space between the < and the ::, because the
+// ridiculous C++ standard defines "<:" to be a synonym for "[".
+const char* PrimitiveTypeName(FieldDescriptor::CppType type);
+
+// Get the declared type name in CamelCase format, as is used e.g. for the
+// methods of WireFormat.  For example, TYPE_INT32 becomes "Int32".
+const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
+
+// Convert a file name into a valid identifier.
+string FilenameIdentifier(const string& filename);
+
+// Return the name of the BuildDescriptors() function for a given file.
+string GlobalBuildDescriptorsName(const string& filename);
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
new file mode 100644
index 0000000..002b0ad
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -0,0 +1,1445 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <algorithm>
+#include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/compiler/cpp/cpp_message.h>
+#include <google/protobuf/compiler/cpp/cpp_enum.h>
+#include <google/protobuf/compiler/cpp/cpp_extension.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+
+namespace {
+
+void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
+  // Print the field's proto-syntax definition as a comment.  We don't want to
+  // print group bodies so we cut off after the first line.
+  string def = field->DebugString();
+  printer->Print("// $def$\n",
+    "def", def.substr(0, def.find_first_of('\n')));
+}
+
+struct FieldOrderingByNumber {
+  inline bool operator()(const FieldDescriptor* a,
+                         const FieldDescriptor* b) const {
+    return a->number() < b->number();
+  }
+};
+
+const char* kWireTypeNames[] = {
+  "VARINT",
+  "FIXED64",
+  "LENGTH_DELIMITED",
+  "START_GROUP",
+  "END_GROUP",
+  "FIXED32",
+};
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it.
+const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
+  const FieldDescriptor** fields =
+    new const FieldDescriptor*[descriptor->field_count()];
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    fields[i] = descriptor->field(i);
+  }
+  sort(fields, fields + descriptor->field_count(),
+       FieldOrderingByNumber());
+  return fields;
+}
+
+// Functor for sorting extension ranges by their "start" field number.
+struct ExtensionRangeSorter {
+  bool operator()(const Descriptor::ExtensionRange* left,
+                  const Descriptor::ExtensionRange* right) const {
+    return left->start < right->start;
+  }
+};
+
+// Returns true if the message type has any required fields.  If it doesn't,
+// we can optimize out calls to its IsInitialized() method.
+//
+// already_seen is used to avoid checking the same type multiple times
+// (and also to protect against recursion).
+static bool HasRequiredFields(
+    const Descriptor* type,
+    hash_set<const Descriptor*>* already_seen) {
+  if (already_seen->count(type) > 0) {
+    // Since the first occurrence of a required field causes the whole
+    // function to return true, we can assume that if the type is already
+    // in the cache it didn't have any required fields.
+    return false;
+  }
+  already_seen->insert(type);
+
+  // If the type has extensions, an extension with message type could contain
+  // required fields, so we have to be conservative and assume such an
+  // extension exists.
+  if (type->extension_range_count() > 0) return true;
+
+  for (int i = 0; i < type->field_count(); i++) {
+    const FieldDescriptor* field = type->field(i);
+    if (field->is_required()) {
+      return true;
+    }
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (HasRequiredFields(field->message_type(), already_seen)) {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+static bool HasRequiredFields(const Descriptor* type) {
+  hash_set<const Descriptor*> already_seen;
+  return HasRequiredFields(type, &already_seen);
+}
+
+}
+
+// ===================================================================
+
+MessageGenerator::MessageGenerator(const Descriptor* descriptor,
+                                   const string& dllexport_decl)
+  : descriptor_(descriptor),
+    classname_(ClassName(descriptor, false)),
+    dllexport_decl_(dllexport_decl),
+    field_generators_(descriptor),
+    nested_generators_(new scoped_ptr<MessageGenerator>[
+      descriptor->nested_type_count()]),
+    enum_generators_(new scoped_ptr<EnumGenerator>[
+      descriptor->enum_type_count()]),
+    extension_generators_(new scoped_ptr<ExtensionGenerator>[
+      descriptor->extension_count()]) {
+
+  for (int i = 0; i < descriptor->nested_type_count(); i++) {
+    nested_generators_[i].reset(
+      new MessageGenerator(descriptor->nested_type(i), dllexport_decl));
+  }
+
+  for (int i = 0; i < descriptor->enum_type_count(); i++) {
+    enum_generators_[i].reset(
+      new EnumGenerator(descriptor->enum_type(i), dllexport_decl));
+  }
+
+  for (int i = 0; i < descriptor->extension_count(); i++) {
+    extension_generators_[i].reset(
+      new ExtensionGenerator(descriptor->extension(i), dllexport_decl));
+  }
+}
+
+MessageGenerator::~MessageGenerator() {}
+
+void MessageGenerator::
+GenerateForwardDeclaration(io::Printer* printer) {
+  printer->Print("class $classname$;\n",
+                 "classname", classname_);
+
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateForwardDeclaration(printer);
+  }
+}
+
+void MessageGenerator::
+GenerateEnumDefinitions(io::Printer* printer) {
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateEnumDefinitions(printer);
+  }
+
+  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+    enum_generators_[i]->GenerateDefinition(printer);
+  }
+}
+
+void MessageGenerator::
+GenerateFieldAccessorDeclarations(io::Printer* printer) {
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    PrintFieldComment(printer, field);
+
+    map<string, string> vars;
+    vars["name"] = FieldName(field);
+
+    if (field->is_repeated()) {
+      printer->Print(vars, "inline int $name$_size() const;\n");
+    } else {
+      printer->Print(vars, "inline bool has_$name$() const;\n");
+    }
+
+    printer->Print(vars, "inline void clear_$name$();\n");
+
+    // Generate type-specific accessor declarations.
+    field_generators_.get(field).GenerateAccessorDeclarations(printer);
+
+    printer->Print("\n");
+  }
+
+  if (descriptor_->extension_range_count() > 0) {
+    // Generate accessors for extensions.
+
+    // Normally I'd generate prototypes here and generate the actual
+    // definitions of these methods in GenerateFieldAccessorDefinitions, but
+    // the prototypes for these silly methods are so absurdly complicated that
+    // it meant way too much repitition.
+    //
+    // We use "_proto_TypeTraits" as a type name below because "TypeTraits"
+    // causes problems if the class has a nested message or enum type with that
+    // name and "_TypeTraits" is technically reserved for the C++ library since
+    // it starts with an underscore followed by a capital letter.
+    printer->Print(
+      // Has, Size, Clear
+      "template <typename _proto_TypeTraits>\n"
+      "inline bool HasExtension(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id) const {\n"
+      "  return _extensions_.Has(id.number());\n"
+      "}\n"
+      "\n"
+      "template <typename _proto_TypeTraits>\n"
+      "inline void ClearExtension(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id) {\n"
+      "  _extensions_.ClearExtension(id.number());\n"
+      "}\n"
+      "\n"
+      "template <typename _proto_TypeTraits>\n"
+      "inline int ExtensionSize(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id) const {\n"
+      "  return _extensions_.ExtensionSize(id.number());\n"
+      "}\n"
+      "\n"
+
+      // Singular accessors
+      "template <typename _proto_TypeTraits>\n"
+      "inline typename _proto_TypeTraits::ConstType GetExtension(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id) const {\n"
+      "  return _proto_TypeTraits::Get(id.number(), _extensions_);\n"
+      "}\n"
+      "\n"
+      "template <typename _proto_TypeTraits>\n"
+      "inline typename _proto_TypeTraits::MutableType MutableExtension(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id) {\n"
+      "  return _proto_TypeTraits::Mutable(id.number(), &_extensions_);\n"
+      "}\n"
+      "\n"
+      "template <typename _proto_TypeTraits>\n"
+      "inline void SetExtension(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id,\n"
+      "    typename _proto_TypeTraits::ConstType value) {\n"
+      "  _proto_TypeTraits::Set(id.number(), value, &_extensions_);\n"
+      "}\n"
+      "\n"
+
+      // Repeated accessors
+      "template <typename _proto_TypeTraits>\n"
+      "inline typename _proto_TypeTraits::ConstType GetExtension(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id,\n"
+      "    int index) const {\n"
+      "  return _proto_TypeTraits::Get(id.number(), _extensions_, index);\n"
+      "}\n"
+      "\n"
+      "template <typename _proto_TypeTraits>\n"
+      "inline typename _proto_TypeTraits::MutableType MutableExtension(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id,\n"
+      "    int index) {\n"
+      "  return _proto_TypeTraits::Mutable(id.number(),index,&_extensions_);\n"
+      "}\n"
+      "\n"
+      "template <typename _proto_TypeTraits>\n"
+      "inline void SetExtension(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id,\n"
+      "    int index, typename _proto_TypeTraits::ConstType value) {\n"
+      "  _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);\n"
+      "}\n"
+      "\n"
+      "template <typename _proto_TypeTraits>\n"
+      "inline typename _proto_TypeTraits::MutableType AddExtension(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id) {\n"
+      "  return _proto_TypeTraits::Add(id.number(), &_extensions_);\n"
+      "}\n"
+      "\n"
+      "template <typename _proto_TypeTraits>\n"
+      "inline void AddExtension(\n"
+      "    const ::google::protobuf::internal::ExtensionIdentifier<\n"
+      "      $classname$, _proto_TypeTraits>& id,\n"
+      "    typename _proto_TypeTraits::ConstType value) {\n"
+      "  _proto_TypeTraits::Add(id.number(), value, &_extensions_);\n"
+      "}\n",
+      "classname", classname_);
+  }
+}
+
+void MessageGenerator::
+GenerateFieldAccessorDefinitions(io::Printer* printer) {
+  printer->Print("// $classname$\n\n", "classname", classname_);
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    PrintFieldComment(printer, field);
+
+    map<string, string> vars;
+    vars["name"] = FieldName(field);
+    vars["index"] = SimpleItoa(field->index());
+    vars["classname"] = classname_;
+
+    // Generate has_$name$() or $name$_size().
+    if (field->is_repeated()) {
+      printer->Print(vars,
+        "inline int $classname$::$name$_size() const {\n"
+        "  return $name$_.size();\n"
+        "}\n");
+    } else {
+      // Singular field.
+      printer->Print(vars,
+        "inline bool $classname$::has_$name$() const {\n"
+        "  return _has_bit($index$);\n"
+        "}\n");
+    }
+
+    // Generate clear_$name$()
+    printer->Print(vars,
+      "inline void $classname$::clear_$name$() {\n");
+
+    printer->Indent();
+    field_generators_.get(field).GenerateClearingCode(printer);
+    printer->Outdent();
+
+    if (!field->is_repeated()) {
+      printer->Print(vars, "  _clear_bit($index$);\n");
+    }
+
+    printer->Print("}\n");
+
+    // Generate type-specific accessors.
+    field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
+
+    printer->Print("\n");
+  }
+}
+
+void MessageGenerator::
+GenerateClassDefinition(io::Printer* printer) {
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateClassDefinition(printer);
+    printer->Print("\n");
+    printer->Print(kThinSeparator);
+    printer->Print("\n");
+  }
+
+  map<string, string> vars;
+  vars["classname"] = classname_;
+  vars["field_count"] = SimpleItoa(descriptor_->field_count());
+  if (dllexport_decl_.empty()) {
+    vars["dllexport"] = "";
+  } else {
+    vars["dllexport"] = dllexport_decl_ + " ";
+  }
+
+  printer->Print(vars,
+    "class $dllexport$$classname$ : public ::google::protobuf::Message {\n"
+    " public:\n");
+  printer->Indent();
+
+  printer->Print(vars,
+    "$classname$();\n"
+    "virtual ~$classname$();\n"
+    "\n"
+    "$classname$(const $classname$& from);\n"
+    "\n"
+    "inline $classname$& operator=(const $classname$& from) {\n"
+    "  CopyFrom(from);\n"
+    "  return *this;\n"
+    "}\n"
+    "\n"
+    "inline static const $classname$& default_instance() {\n"
+    "  return default_instance_;\n"
+    "}\n"
+    "\n"
+    "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
+    "  return _reflection_.unknown_fields();\n"
+    "}\n"
+    "\n"
+    "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
+    "  return _reflection_.mutable_unknown_fields();\n"
+    "}\n"
+    "\n"
+    "static const ::google::protobuf::Descriptor* descriptor();\n"
+    "\n"
+    "// implements Message ----------------------------------------------\n"
+    "\n"
+    "$classname$* New() const;\n");
+
+  if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+    printer->Print(vars,
+      "void CopyFrom(const ::google::protobuf::Message& from);\n"
+      "void MergeFrom(const ::google::protobuf::Message& from);\n"
+      "void CopyFrom(const $classname$& from);\n"
+      "void MergeFrom(const $classname$& from);\n"
+      "void Clear();\n"
+      "bool IsInitialized() const;\n"
+      "int ByteSize() const;\n"
+      "\n"
+      "bool MergePartialFromCodedStream(\n"
+      "    ::google::protobuf::io::CodedInputStream* input);\n"
+      "bool SerializeWithCachedSizes(\n"
+      "    ::google::protobuf::io::CodedOutputStream* output) const;\n");
+  }
+
+  printer->Print(vars,
+    "int GetCachedSize() const { return _cached_size_; }\n"
+    "private:\n"
+    "void SetCachedSize(int size) const { _cached_size_ = size; }\n"
+    "public:\n"
+    "\n"
+    "const ::google::protobuf::Descriptor* GetDescriptor() const;\n"
+    "const ::google::protobuf::Message::Reflection* GetReflection() const;\n"
+    "::google::protobuf::Message::Reflection* GetReflection();\n"
+    "\n"
+    "// nested types ----------------------------------------------------\n"
+    "\n");
+
+  // Import all nested message classes into this class's scope with typedefs.
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    const Descriptor* nested_type = descriptor_->nested_type(i);
+    printer->Print("typedef $nested_full_name$ $nested_name$;\n",
+                   "nested_name", nested_type->name(),
+                   "nested_full_name", ClassName(nested_type, false));
+  }
+
+  if (descriptor_->nested_type_count() > 0) {
+    printer->Print("\n");
+  }
+
+  // Import all nested enums and their values into this class's scope with
+  // typedefs and constants.
+  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+    enum_generators_[i]->GenerateSymbolImports(printer);
+    printer->Print("\n");
+  }
+
+  printer->Print(
+    "// accessors -------------------------------------------------------\n"
+    "\n");
+
+  // Generate accessor methods for all fields.
+  GenerateFieldAccessorDeclarations(printer);
+
+  // Declare extension identifiers.
+  for (int i = 0; i < descriptor_->extension_count(); i++) {
+    extension_generators_[i]->GenerateDeclaration(printer);
+  }
+
+  // Generate private members for fields.
+  printer->Outdent();
+  printer->Print(" private:\n");
+  printer->Indent();
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "::google::protobuf::internal::ExtensionSet _extensions_;\n");
+  }
+
+  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
+  printer->Print(
+    "::google::protobuf::internal::GeneratedMessageReflection _reflection_;\n"
+    "mutable int _cached_size_;\n"
+    "\n");
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i))
+                     .GeneratePrivateMembers(printer);
+  }
+
+  // Generate offsets and _has_bits_ boilerplate.
+  printer->Print(vars,
+    "\n"
+    "static const $classname$ default_instance_;\n");
+
+  if (descriptor_->field_count() > 0) {
+    printer->Print(vars,
+      "static const int _offsets_[$field_count$];\n"
+      "\n"
+      "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n");
+  } else {
+    // Zero-size arrays aren't technically allowed, and MSVC in particular
+    // doesn't like them.  We still need to declare these arrays to make
+    // other code compile.  Since this is an uncommon case, we'll just declare
+    // them with size 1 and waste some space.  Oh well.
+    printer->Print(
+      "static const int _offsets_[1];\n"
+      "\n"
+      "::google::protobuf::uint32 _has_bits_[1];\n");
+  }
+
+  printer->Print(
+    "\n"
+    "// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?\n"
+    "inline bool _has_bit(int index) const {\n"
+    "  return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;\n"
+    "}\n"
+    "inline void _set_bit(int index) {\n"
+    "  _has_bits_[index / 32] |= (1u << (index % 32));\n"
+    "}\n"
+    "inline void _clear_bit(int index) {\n"
+    "  _has_bits_[index / 32] &= ~(1u << (index % 32));\n"
+    "}\n");
+
+  printer->Outdent();
+  printer->Print(vars, "};");
+}
+
+void MessageGenerator::
+GenerateInlineMethods(io::Printer* printer) {
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateInlineMethods(printer);
+    printer->Print(kThinSeparator);
+    printer->Print("\n");
+  }
+
+  GenerateFieldAccessorDefinitions(printer);
+}
+
+void MessageGenerator::
+GenerateDescriptorDeclarations(io::Printer* printer) {
+  printer->Print("const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n",
+                 "name", classname_);
+
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateDescriptorDeclarations(printer);
+  }
+
+  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+    printer->Print(
+      "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
+      "name", ClassName(descriptor_->enum_type(i), false));
+  }
+}
+
+void MessageGenerator::
+GenerateDescriptorInitializer(io::Printer* printer, int index) {
+  // TODO(kenton):  Passing the index to this method is redundant; just use
+  //   descriptor_->index() instead.
+  map<string, string> vars;
+  vars["classname"] = classname_;
+  vars["index"] = SimpleItoa(index);
+
+  if (descriptor_->containing_type() == NULL) {
+    printer->Print(vars,
+      "$classname$_descriptor_ = file->message_type($index$);\n");
+  } else {
+    vars["parent"] = ClassName(descriptor_->containing_type(), false);
+    printer->Print(vars,
+      "$classname$_descriptor_ = "
+        "$parent$_descriptor_->nested_type($index$);\n");
+  }
+
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
+  }
+
+  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+    enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
+  }
+
+  // Register this message type with the message factory.
+  printer->Print(vars,
+    "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
+    "  $classname$_descriptor_, &$classname$::default_instance());\n");
+}
+
+void MessageGenerator::
+GenerateClassMethods(io::Printer* printer) {
+  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+    enum_generators_[i]->GenerateMethods(printer);
+  }
+
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateClassMethods(printer);
+    printer->Print("\n");
+    printer->Print(kThinSeparator);
+    printer->Print("\n");
+  }
+
+  printer->Print(
+    "const $classname$ $classname$::default_instance_;\n"
+    "\n",
+    "classname", classname_);
+
+  // Generate non-inline field definitions.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i))
+                     .GenerateNonInlineAccessorDefinitions(printer);
+    printer->Print("\n");
+  }
+
+  // Define extension identifiers.
+  for (int i = 0; i < descriptor_->extension_count(); i++) {
+    extension_generators_[i]->GenerateDefinition(printer);
+  }
+
+  GenerateOffsets(printer);
+  printer->Print("\n");
+
+  GenerateStructors(printer);
+  printer->Print("\n");
+
+  if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+    GenerateClear(printer);
+    printer->Print("\n");
+
+    GenerateMergeFromCodedStream(printer);
+    printer->Print("\n");
+
+    GenerateSerializeWithCachedSizes(printer);
+    printer->Print("\n");
+
+    GenerateByteSize(printer);
+    printer->Print("\n");
+
+    GenerateMergeFrom(printer);
+    printer->Print("\n");
+
+    GenerateCopyFrom(printer);
+    printer->Print("\n");
+
+    GenerateIsInitialized(printer);
+    printer->Print("\n");
+  }
+
+  printer->Print(
+    "const ::google::protobuf::Descriptor* $classname$::GetDescriptor() const {\n"
+    "  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"
+    "}\n",
+    "classname", classname_);
+}
+
+void MessageGenerator::
+GenerateOffsets(io::Printer* printer) {
+  printer->Print(
+    "const int $classname$::_offsets_[$field_count$] = {\n",
+    "classname", classname_,
+    "field_count", SimpleItoa(max(1, descriptor_->field_count())));
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    printer->Print(
+      "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
+      "classname", classname_,
+      "name", FieldName(field));
+  }
+
+  printer->Outdent();
+  printer->Print("};\n");
+}
+
+void MessageGenerator::
+GenerateInitializerList(io::Printer* printer) {
+  printer->Indent();
+  printer->Indent();
+
+  bool has_extensions = descriptor_->extension_range_count() > 0;
+  if (has_extensions) {
+    printer->Print(
+      "_extensions_(descriptor(),\n"
+      "             ::google::protobuf::DescriptorPool::generated_pool(),\n"
+      "             ::google::protobuf::MessageFactory::generated_factory()),\n");
+  }
+
+  printer->Print(
+    "_reflection_(descriptor(),\n"
+    "             this, &default_instance_,\n"
+    "             _offsets_, _has_bits_, $extensions$),\n"
+    "_cached_size_(0)",
+    "extensions", has_extensions ? "&_extensions_" : "NULL");
+
+  // Write the initializers for each field.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i))
+                     .GenerateInitializer(printer);
+  }
+
+  printer->Outdent();
+  printer->Outdent();
+}
+
+void MessageGenerator::
+GenerateStructors(io::Printer* printer) {
+  // Generate the default constructor.
+  printer->Print(
+      "$classname$::$classname$()\n"
+      "  : ",
+      "classname", classname_);
+  GenerateInitializerList(printer);
+  printer->Print(" {\n"
+    "  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n"
+    "  if (this == &default_instance_) {\n");
+
+  // The default instance needs all of its embedded message pointers
+  // cross-linked to other default instances.
+  // TODO(kenton):  Maybe all message fields (even for non-default messages)
+  //   should be initialized to point at default instances rather than NULL?
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    if (!field->is_repeated() &&
+        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      printer->Print(
+          "    $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
+          "name", FieldName(field),
+          "type", ClassName(field->message_type(), true));
+    }
+  }
+  printer->Print(
+    "  }\n"
+    "}\n"
+    "\n");
+
+  // Generate the copy constructor.
+  printer->Print(
+      "$classname$::$classname$(const $classname$& from)\n"
+      "  : ",
+      "classname", classname_);
+  GenerateInitializerList(printer);
+  printer->Print(" {\n"
+    "  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n"
+    "  MergeFrom(from);\n"
+    "}\n"
+    "\n");
+
+  // Generate the destructor.
+  printer->Print(
+    "$classname$::~$classname$() {\n",
+    "classname", classname_);
+
+  printer->Indent();
+
+  // Write the destructors for each field.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i))
+                     .GenerateDestructorCode(printer);
+  }
+
+  printer->Print(
+    "if (this != &default_instance_) {\n");
+
+  // We need to delete all embedded messages.
+  // TODO(kenton):  If we make unset messages point at default instances
+  //   instead of NULL, then it would make sense to move this code into
+  //   MessageFieldGenerator::GenerateDestructorCode().
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    if (!field->is_repeated() &&
+        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      printer->Print("  delete $name$_;\n",
+                     "name", FieldName(field));
+    }
+  }
+
+  printer->Outdent();
+
+  printer->Print(
+    "  }\n"
+    "}\n"
+    "\n"
+    "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
+    "  if ($classname$_descriptor_ == NULL) $builddescriptorsname$();\n"
+    "  return $classname$_descriptor_;\n"
+    "}\n"
+    "\n"
+    "$classname$* $classname$::New() const {\n"
+    "  return new $classname$;\n"
+    "}\n",
+    "classname", classname_,
+    "builddescriptorsname",
+    GlobalBuildDescriptorsName(descriptor_->file()->name()));
+}
+
+void MessageGenerator::
+GenerateClear(io::Printer* printer) {
+  printer->Print("void $classname$::Clear() {\n",
+                 "classname", classname_);
+  printer->Indent();
+
+  int last_index = -1;
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print("_extensions_.Clear();\n");
+  }
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    if (!field->is_repeated()) {
+      map<string, string> vars;
+      vars["index"] = SimpleItoa(field->index());
+
+      // We can use the fact that _has_bits_ is a giant bitfield to our
+      // advantage:  We can check up to 32 bits at a time for equality to
+      // zero, and skip the whole range if so.  This can improve the speed
+      // of Clear() for messages which contain a very large number of
+      // optional fields of which only a few are used at a time.  Here,
+      // we've chosen to check 8 bits at a time rather than 32.
+      if (i / 8 != last_index / 8 || last_index < 0) {
+        if (last_index >= 0) {
+          printer->Outdent();
+          printer->Print("}\n");
+        }
+        printer->Print(vars,
+          "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
+        printer->Indent();
+      }
+      last_index = i;
+
+      // It's faster to just overwrite primitive types, but we should
+      // only clear strings and messages if they were set.
+      // TODO(kenton):  Let the CppFieldGenerator decide this somehow.
+      bool should_check_bit =
+        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
+        field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
+
+      if (should_check_bit) {
+        printer->Print(vars, "if (_has_bit($index$)) {\n");
+        printer->Indent();
+      }
+
+      field_generators_.get(field).GenerateClearingCode(printer);
+
+      if (should_check_bit) {
+        printer->Outdent();
+        printer->Print("}\n");
+      }
+    }
+  }
+
+  if (last_index >= 0) {
+    printer->Outdent();
+    printer->Print("}\n");
+  }
+
+  // Repeated fields don't use _has_bits_ so we clear them in a separate
+  // pass.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    if (field->is_repeated()) {
+      field_generators_.get(field).GenerateClearingCode(printer);
+    }
+  }
+
+  printer->Print(
+    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"
+    "mutable_unknown_fields()->Clear();\n");
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateMergeFrom(io::Printer* printer) {
+  // Generate the generalized MergeFrom (aka that which takes in the Message
+  // base class as a parameter).
+  printer->Print(
+    "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
+    "  GOOGLE_CHECK_NE(&from, this);\n",
+    "classname", classname_);
+  printer->Indent();
+
+  if (descriptor_->field_count() > 0) {
+    // Cast the message to the proper type. If we find that the message is
+    // *not* of the proper type, we can still call Merge via the reflection
+    // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
+    // for each message.
+    printer->Print(
+      "const $classname$* source =\n"
+      "  ::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"
+      "} else {\n"
+      "  MergeFrom(*source);\n"
+      "}\n",
+      "classname", classname_);
+  }
+
+  printer->Outdent();
+  printer->Print("}\n\n");
+
+  // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
+  printer->Print(
+    "void $classname$::MergeFrom(const $classname$& from) {\n"
+    "  GOOGLE_CHECK_NE(&from, this);\n",
+    "classname", classname_);
+  printer->Indent();
+
+  // Merge Repeated fields. These fields do not require a
+  // check as we can simply iterate over them.
+  for (int i = 0; i < descriptor_->field_count(); ++i) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    if (field->is_repeated()) {
+      field_generators_.get(field).GenerateMergingCode(printer);
+    }
+  }
+
+  // Merge Optional and Required fields (after a _has_bit check).
+  int last_index = -1;
+
+  for (int i = 0; i < descriptor_->field_count(); ++i) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    if (!field->is_repeated()) {
+      map<string, string> vars;
+      vars["index"] = SimpleItoa(field->index());
+
+      // See above in GenerateClear for an explanation of this.
+      if (i / 8 != last_index / 8 || last_index < 0) {
+        if (last_index >= 0) {
+          printer->Outdent();
+          printer->Print("}\n");
+        }
+        printer->Print(vars,
+          "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
+        printer->Indent();
+      }
+
+      last_index = i;
+
+      printer->Print(vars,
+        "if (from._has_bit($index$)) {\n");
+      printer->Indent();
+
+      field_generators_.get(field).GenerateMergingCode(printer);
+
+      printer->Outdent();
+      printer->Print("}\n");
+    }
+  }
+
+  if (last_index >= 0) {
+    printer->Outdent();
+    printer->Print("}\n");
+  }
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
+  }
+
+  printer->Print(
+    "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateCopyFrom(io::Printer* printer) {
+  // Generate the generalized CopyFrom (aka that which takes in the Message
+  // base class as a parameter).
+  printer->Print(
+    "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
+    "classname", classname_);
+  printer->Indent();
+
+  printer->Print(
+    "if (&from == this) return;\n"
+    "Clear();\n"
+    "MergeFrom(from);\n");
+
+  printer->Outdent();
+  printer->Print("}\n\n");
+
+  // Generate the class-specific CopyFrom.
+  printer->Print(
+    "void $classname$::CopyFrom(const $classname$& from) {\n",
+    "classname", classname_);
+  printer->Indent();
+
+  printer->Print(
+    "if (&from == this) return;\n"
+    "Clear();\n"
+    "MergeFrom(from);\n");
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) {
+  if (descriptor_->options().message_set_wire_format()) {
+    // For message_set_wire_format, we don't generate a parser, for two
+    // reasons:
+    // - WireFormat already needs to special-case this, and we'd like to
+    //   avoid having multiple implementations of MessageSet wire format
+    //   lying around the code base.
+    // - All fields are extensions, and extension parsing falls back to
+    //   reflection anyway, so it wouldn't be any faster.
+    printer->Print(
+      "bool $classname$::MergePartialFromCodedStream(\n"
+      "    ::google::protobuf::io::CodedInputStream* input) {\n"
+      "  return ::google::protobuf::internal::WireFormat::ParseAndMergePartial(\n"
+      "    descriptor(), input, &_reflection_);\n"
+      "}\n",
+      "classname", classname_);
+    return;
+  }
+
+  printer->Print(
+    "bool $classname$::MergePartialFromCodedStream(\n"
+    "    ::google::protobuf::io::CodedInputStream* input) {\n"
+    "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n"
+    "  ::google::protobuf::uint32 tag;\n"
+    "  while ((tag = input->ReadTag()) != 0) {\n",
+    "classname", classname_);
+
+  printer->Indent();
+  printer->Indent();
+
+  if (descriptor_->field_count() > 0) {
+    // We don't even want to print the switch() if we have no fields because
+    // MSVC dislikes switch() statements that contain only a default value.
+
+    // Note:  If we just switched on the tag rather than the field number, we
+    // could avoid the need for the if() to check the wire type at the beginning
+    // of each case.  However, this is actually a bit slower in practice as it
+    // creates a jump table that is 8x larger and sparser, and meanwhile the
+    // if()s are highly predictable.
+    printer->Print(
+      "switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) {\n");
+
+    printer->Indent();
+
+    scoped_array<const FieldDescriptor*> ordered_fields(
+      SortFieldsByNumber(descriptor_));
+
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      const FieldDescriptor* field = ordered_fields[i];
+
+      PrintFieldComment(printer, field);
+
+      printer->Print(
+        "case $number$: {\n"
+        "  if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=\n"
+        "      ::google::protobuf::internal::WireFormat::WIRETYPE_$wiretype$) {\n"
+        "    goto handle_uninterpreted;\n"
+        "  }\n",
+        "number", SimpleItoa(field->number()),
+        "wiretype", kWireTypeNames[
+          WireFormat::WireTypeForFieldType(field->type())]);
+
+      if (i > 0 || field->is_repeated()) {
+        printer->Print(
+          " parse_$name$:\n",
+          "name", field->name());
+      }
+
+      printer->Indent();
+
+      field_generators_.get(field).GenerateMergeFromCodedStream(printer);
+
+      // switch() is slow since it can't be predicted well.  Insert some if()s
+      // here that attempt to predict the next tag.
+      if (field->is_repeated()) {
+        // Expect repeats of this field.
+        printer->Print(
+          "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
+          "tag", SimpleItoa(WireFormat::MakeTag(field)),
+          "name", field->name());
+      }
+
+      if (i + 1 < descriptor_->field_count()) {
+        // Expect the next field in order.
+        const FieldDescriptor* next_field = ordered_fields[i + 1];
+        printer->Print(
+          "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
+          "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
+          "next_name", next_field->name());
+      } else {
+        // Expect EOF.
+        // TODO(kenton):  Expect group end-tag?
+        printer->Print(
+          "if (input->ExpectAtEnd()) return true;\n");
+      }
+
+      printer->Print(
+        "break;\n");
+
+      printer->Outdent();
+      printer->Print("}\n\n");
+    }
+
+    printer->Print(
+      "default: {\n"
+      "handle_uninterpreted:\n");
+    printer->Indent();
+  }
+
+  // Is this an end-group tag?  If so, this must be the end of the message.
+  printer->Print(
+    "if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) ==\n"
+    "    ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) {\n"
+    "  return true;\n"
+    "}\n");
+
+  // Handle extension ranges.
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "if (");
+    for (int i = 0; i < descriptor_->extension_range_count(); i++) {
+      const Descriptor::ExtensionRange* range =
+        descriptor_->extension_range(i);
+      if (i > 0) printer->Print(" &&\n    ");
+
+      uint32 start_tag = WireFormat::MakeTag(
+        range->start, static_cast<WireFormat::WireType>(0));
+      uint32 end_tag = WireFormat::MakeTag(
+        range->end, static_cast<WireFormat::WireType>(0));
+
+      if (range->end > FieldDescriptor::kMaxNumber) {
+        printer->Print(
+          "($start$u <= tag)",
+          "start", SimpleItoa(start_tag));
+      } else {
+        printer->Print(
+          "($start$u <= tag && tag < $end$u)",
+          "start", SimpleItoa(start_tag),
+          "end", SimpleItoa(end_tag));
+      }
+    }
+    printer->Print(") {\n"
+      "  DO_(_extensions_.ParseField(tag, input, &_reflection_));\n"
+      "  continue;\n"
+      "}\n");
+  }
+
+  // We really don't recognize this tag.  Skip it.
+  printer->Print(
+    "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
+    "      input, tag, mutable_unknown_fields()));\n");
+
+  if (descriptor_->field_count() > 0) {
+    printer->Print("break;\n");
+    printer->Outdent();
+    printer->Print("}\n");    // default:
+    printer->Outdent();
+    printer->Print("}\n");    // switch
+  }
+
+  printer->Outdent();
+  printer->Outdent();
+  printer->Print(
+    "  }\n"                   // while
+    "  return true;\n"
+    "#undef DO_\n"
+    "}\n");
+}
+
+void MessageGenerator::GenerateSerializeOneField(
+    io::Printer* printer, const FieldDescriptor* field) {
+  PrintFieldComment(printer, field);
+
+  if (field->is_repeated()) {
+    printer->Print(
+      "for (int i = 0; i < $name$_.size(); i++) {\n",
+      "name", FieldName(field));
+  } else {
+    printer->Print(
+      "if (_has_bit($index$)) {\n",
+      "index", SimpleItoa(field->index()));
+  }
+
+  printer->Indent();
+
+  field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
+
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+void MessageGenerator::GenerateSerializeOneExtensionRange(
+    io::Printer* printer, const Descriptor::ExtensionRange* range) {
+  map<string, string> vars;
+  vars["start"] = SimpleItoa(range->start);
+  vars["end"] = SimpleItoa(range->end);
+  printer->Print(vars,
+    "// Extension range [$start$, $end$)\n"
+    "DO_(_extensions_.SerializeWithCachedSizes(\n"
+    "    $start$, $end$, &_reflection_, output));\n\n");
+}
+
+void MessageGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) {
+  printer->Print(
+    "bool $classname$::SerializeWithCachedSizes(\n"
+    "    ::google::protobuf::io::CodedOutputStream* output) const {\n"
+    "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n",
+    "classname", classname_);
+  printer->Indent();
+
+  scoped_array<const FieldDescriptor*> ordered_fields(
+    SortFieldsByNumber(descriptor_));
+
+  vector<const Descriptor::ExtensionRange*> sorted_extensions;
+  for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+    sorted_extensions.push_back(descriptor_->extension_range(i));
+  }
+  sort(sorted_extensions.begin(), sorted_extensions.end(),
+       ExtensionRangeSorter());
+
+  // Merge the fields and the extension ranges, both sorted by field number.
+  int i, j;
+  for (i = 0, j = 0;
+       i < descriptor_->field_count() || j < sorted_extensions.size();
+       ) {
+    if (i == descriptor_->field_count()) {
+      GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
+    } else if (j == sorted_extensions.size()) {
+      GenerateSerializeOneField(printer, ordered_fields[i++]);
+    } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
+      GenerateSerializeOneField(printer, ordered_fields[i++]);
+    } else {
+      GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
+    }
+  }
+
+  printer->Print("if (!unknown_fields().empty()) {\n");
+  printer->Indent();
+  if (descriptor_->options().message_set_wire_format()) {
+    printer->Print(
+      "DO_(::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
+      "    unknown_fields(), output));\n");
+  } else {
+    printer->Print(
+      "DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
+      "    unknown_fields(), output));\n");
+  }
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "return true;\n");
+
+  printer->Outdent();
+  printer->Print(
+    "#undef DO_\n"
+    "}\n");
+}
+
+void MessageGenerator::
+GenerateByteSize(io::Printer* printer) {
+  printer->Print(
+    "int $classname$::ByteSize() const {\n",
+    "classname", classname_);
+  printer->Indent();
+  printer->Print(
+    "int total_size = 0;\n"
+    "\n");
+
+  int last_index = -1;
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    if (!field->is_repeated()) {
+      // See above in GenerateClear for an explanation of this.
+      // TODO(kenton):  Share code?  Unclear how to do so without
+      //   over-engineering.
+      if ((i / 8) != (last_index / 8) ||
+          last_index < 0) {
+        if (last_index >= 0) {
+          printer->Outdent();
+          printer->Print("}\n");
+        }
+        printer->Print(
+          "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
+          "index", SimpleItoa(field->index()));
+        printer->Indent();
+      }
+      last_index = i;
+
+      PrintFieldComment(printer, field);
+
+      printer->Print(
+        "if (has_$name$()) {\n",
+        "name", FieldName(field));
+      printer->Indent();
+
+      field_generators_.get(field).GenerateByteSize(printer);
+
+      printer->Outdent();
+      printer->Print(
+        "}\n"
+        "\n");
+    }
+  }
+
+  if (last_index >= 0) {
+    printer->Outdent();
+    printer->Print("}\n");
+  }
+
+  // Repeated fields don't use _has_bits_ so we count them in a separate
+  // pass.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    if (field->is_repeated()) {
+      PrintFieldComment(printer, field);
+      field_generators_.get(field).GenerateByteSize(printer);
+      printer->Print("\n");
+    }
+  }
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "total_size += _extensions_.ByteSize(&_reflection_);\n"
+      "\n");
+  }
+
+  printer->Print("if (!unknown_fields().empty()) {\n");
+  printer->Indent();
+  if (descriptor_->options().message_set_wire_format()) {
+    printer->Print(
+      "total_size +=\n"
+      "  ::google::protobuf::internal::WireFormat::ComputeUnknownMessageSetItemsSize(\n"
+      "    unknown_fields());\n");
+  } else {
+    printer->Print(
+      "total_size +=\n"
+      "  ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
+      "    unknown_fields());\n");
+  }
+  printer->Outdent();
+  printer->Print("}\n");
+
+  // We update _cached_size_ even though this is a const method.  In theory,
+  // this is not thread-compatible, because concurrent writes have undefined
+  // results.  In practice, since any concurrent writes will be writing the
+  // exact same value, it works on all common processors.  In a future version
+  // of C++, _cached_size_ should be made into an atomic<int>.
+  printer->Print(
+    "_cached_size_ = total_size;\n"
+    "return total_size;\n");
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateIsInitialized(io::Printer* printer) {
+  printer->Print(
+    "bool $classname$::IsInitialized() const {\n",
+    "classname", classname_);
+  printer->Indent();
+
+  // Check that all required fields in this message are set.  We can do this
+  // most efficiently by checking 32 "has bits" at a time.
+  int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
+  for (int i = 0; i < has_bits_array_size; i++) {
+    uint32 mask = 0;
+    for (int bit = 0; bit < 32; bit++) {
+      int index = i * 32 + bit;
+      if (index >= descriptor_->field_count()) break;
+      const FieldDescriptor* field = descriptor_->field(index);
+
+      if (field->is_required()) {
+        mask |= 1 << bit;
+      }
+    }
+
+    if (mask != 0) {
+      char buffer[kFastToBufferSize];
+      printer->Print(
+        "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
+        "i", SimpleItoa(i),
+        "mask", FastHex32ToBuffer(mask, buffer));
+    }
+  }
+
+  // Now check that all embedded messages are initialized.
+  printer->Print("\n");
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+        HasRequiredFields(field->message_type())) {
+      if (field->is_repeated()) {
+        printer->Print(
+          "for (int i = 0; i < $name$_size(); i++) {\n"
+          "  if (!this->$name$(i).IsInitialized()) return false;\n"
+          "}\n",
+          "name", FieldName(field));
+      } else {
+        printer->Print(
+          "if (has_$name$()) {\n"
+          "  if (!this->$name$().IsInitialized()) return false;\n"
+          "}\n",
+          "name", FieldName(field));
+      }
+    }
+  }
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "\n"
+      "if (!_extensions_.IsInitialized()) return false;");
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "  return true;\n"
+    "}\n");
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
new file mode 100644
index 0000000..904e048
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -0,0 +1,125 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator;           // enum.h
+class ExtensionGenerator;      // extension.h
+
+class MessageGenerator {
+ public:
+  // See generator.cc for the meaning of dllexport_decl.
+  explicit MessageGenerator(const Descriptor* descriptor,
+                            const string& dllexport_decl);
+  ~MessageGenerator();
+
+  // Header stuff.
+
+  // Generate foward declarations for this class and all its nested types.
+  void GenerateForwardDeclaration(io::Printer* printer);
+
+  // Generate definitions of all nested enums (must come before class
+  // definitions because those classes use the enums definitions).
+  void GenerateEnumDefinitions(io::Printer* printer);
+
+  // Generate definitions for this class and all its nested types.
+  void GenerateClassDefinition(io::Printer* printer);
+
+  // Generate definitions of inline methods (placed at the end of the header
+  // file).
+  void GenerateInlineMethods(io::Printer* printer);
+
+  // Source file stuff.
+
+  // Generate code which declares all the global descriptor pointers which
+  // will be initialized by the methods below.
+  void GenerateDescriptorDeclarations(io::Printer* printer);
+
+  // Generate code that initializes the global variable storing the message's
+  // descriptor.
+  void GenerateDescriptorInitializer(io::Printer* printer, int index);
+
+  // Generate all non-inline methods for this class.
+  void GenerateClassMethods(io::Printer* printer);
+
+ private:
+  // Generate declarations and definitions of accessors for fields.
+  void GenerateFieldAccessorDeclarations(io::Printer* printer);
+  void GenerateFieldAccessorDefinitions(io::Printer* printer);
+
+  // Generate the field offsets array.
+  void GenerateOffsets(io::Printer* printer);
+
+  // Generate constructors and destructor.
+  void GenerateStructors(io::Printer* printer);
+
+  // Generate the member initializer list for the constructors. The member
+  // initializer list is shared between the default constructor and the copy
+  // constructor.
+  void GenerateInitializerList(io::Printer* printer);
+
+  // Generate standard Message methods.
+  void GenerateClear(io::Printer* printer);
+  void GenerateMergeFromCodedStream(io::Printer* printer);
+  void GenerateSerializeWithCachedSizes(io::Printer* printer);
+  void GenerateByteSize(io::Printer* printer);
+  void GenerateMergeFrom(io::Printer* printer);
+  void GenerateCopyFrom(io::Printer* printer);
+  void GenerateIsInitialized(io::Printer* printer);
+
+  // Helpers for GenerateSerializeWithCachedSizes().
+  void GenerateSerializeOneField(io::Printer* printer,
+                                 const FieldDescriptor* field);
+  void GenerateSerializeOneExtensionRange(
+      io::Printer* printer, const Descriptor::ExtensionRange* range);
+
+  const Descriptor* descriptor_;
+  string classname_;
+  string dllexport_decl_;
+  FieldGeneratorMap field_generators_;
+  scoped_array<scoped_ptr<MessageGenerator> > nested_generators_;
+  scoped_array<scoped_ptr<EnumGenerator> > enum_generators_;
+  scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
new file mode 100644
index 0000000..501ca56
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -0,0 +1,229 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_message_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format_inl.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+
+namespace {
+
+// TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
+//   repeat code between this and the other field types.
+void SetMessageVariables(const FieldDescriptor* descriptor,
+                         map<string, string>* variables) {
+  (*variables)["name"] = FieldName(descriptor);
+  (*variables)["type"] = ClassName(descriptor->message_type(), true);
+  (*variables)["index"] = SimpleItoa(descriptor->index());
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
+  (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
+  (*variables)["tag_size"] = SimpleItoa(
+    WireFormat::TagSize(descriptor->number(), descriptor->type()));
+}
+
+}  // namespace
+
+// ===================================================================
+
+MessageFieldGenerator::
+MessageFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetMessageVariables(descriptor, &variables_);
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {}
+
+void MessageFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_, "$type$* $name$_;\n");
+}
+
+void MessageFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const $type$& $name$() const;\n"
+    "inline $type$* mutable_$name$();\n");
+}
+
+void MessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const $type$& $classname$::$name$() const {\n"
+    "  return $name$_ != NULL ? *$name$_ : *default_instance_.$name$_;\n"
+    "}\n"
+    "inline $type$* $classname$::mutable_$name$() {\n"
+    "  _set_bit($index$);\n"
+    "  if ($name$_ == NULL) $name$_ = new $type$;\n"
+    "  return $name$_;\n"
+    "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($name$_ != NULL) $name$_->$type$::Clear();\n");
+}
+
+void MessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
+}
+
+void MessageFieldGenerator::
+GenerateInitializer(io::Printer* printer) const {
+  printer->Print(variables_, ",\n$name$_(NULL)");
+}
+
+void MessageFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+    printer->Print(variables_,
+      "DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(\n"
+      "     input, mutable_$name$()));\n");
+  } else {
+    printer->Print(variables_,
+      "DO_(::google::protobuf::internal::WireFormat::ReadGroupNoVirtual("
+        "$number$, input, mutable_$name$()));\n");
+  }
+}
+
+void MessageFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$NoVirtual("
+      "$number$, this->$name$(), output));\n");
+}
+
+void MessageFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ +\n"
+    "  ::google::protobuf::internal::WireFormat::$declared_type$SizeNoVirtual(\n"
+    "    this->$name$());\n");
+}
+
+// ===================================================================
+
+RepeatedMessageFieldGenerator::
+RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetMessageVariables(descriptor, &variables_);
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+
+void RepeatedMessageFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "::google::protobuf::RepeatedPtrField< $type$ > $name$_;\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedPtrField< $type$ >& $name$() const;\n"
+    "inline ::google::protobuf::RepeatedPtrField< $type$ >* mutable_$name$();\n"
+    "inline const $type$& $name$(int index) const;\n"
+    "inline $type$* mutable_$name$(int index);\n"
+    "inline $type$* add_$name$();\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+    "$classname$::$name$() const {\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+    "$classname$::mutable_$name$() {\n"
+    "  return &$name$_;\n"
+    "}\n"
+    "inline const $type$& $classname$::$name$(int index) const {\n"
+    "  return $name$_.Get(index);\n"
+    "}\n"
+    "inline $type$* $classname$::mutable_$name$(int index) {\n"
+    "  return $name$_.Mutable(index);\n"
+    "}\n"
+    "inline $type$* $classname$::add_$name$() {\n"
+    "  return $name$_.Add();\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateInitializer(io::Printer* printer) const {
+  // Not needed for repeated fields.
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+    printer->Print(variables_,
+      "DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(\n"
+      "     input, add_$name$()));\n");
+  } else {
+    printer->Print(variables_,
+      "DO_(::google::protobuf::internal::WireFormat::ReadGroupNoVirtual("
+        "$number$, input, add_$name$()));\n");
+  }
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$NoVirtual("
+      "$number$, this->$name$(i), output));\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ * $name$_size();\n"
+    "for (int i = 0; i < $name$_size(); i++) {\n"
+    "  total_size +=\n"
+    "    ::google::protobuf::internal::WireFormat::$declared_type$SizeNoVirtual(\n"
+    "      this->$name$(i));\n"
+    "}\n");
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h
new file mode 100644
index 0000000..a2be6b6
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class MessageFieldGenerator : public FieldGenerator {
+ public:
+  explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
+  ~MessageFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GeneratePrivateMembers(io::Printer* printer) const;
+  void GenerateAccessorDeclarations(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateInitializer(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
+};
+
+class RepeatedMessageFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
+  ~RepeatedMessageFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GeneratePrivateMembers(io::Printer* printer) const;
+  void GenerateAccessorDeclarations(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateInitializer(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
new file mode 100644
index 0000000..312ed03
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -0,0 +1,294 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format_inl.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+
+namespace {
+
+// For encodings with fixed sizes, returns that size in bytes.  Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type) {
+  switch (type) {
+    case FieldDescriptor::TYPE_INT32   : return -1;
+    case FieldDescriptor::TYPE_INT64   : return -1;
+    case FieldDescriptor::TYPE_UINT32  : return -1;
+    case FieldDescriptor::TYPE_UINT64  : return -1;
+    case FieldDescriptor::TYPE_SINT32  : return -1;
+    case FieldDescriptor::TYPE_SINT64  : return -1;
+    case FieldDescriptor::TYPE_FIXED32 : return WireFormat::kFixed32Size;
+    case FieldDescriptor::TYPE_FIXED64 : return WireFormat::kFixed64Size;
+    case FieldDescriptor::TYPE_SFIXED32: return WireFormat::kSFixed32Size;
+    case FieldDescriptor::TYPE_SFIXED64: return WireFormat::kSFixed64Size;
+    case FieldDescriptor::TYPE_FLOAT   : return WireFormat::kFloatSize;
+    case FieldDescriptor::TYPE_DOUBLE  : return WireFormat::kDoubleSize;
+
+    case FieldDescriptor::TYPE_BOOL    : return WireFormat::kBoolSize;
+    case FieldDescriptor::TYPE_ENUM    : return -1;
+
+    case FieldDescriptor::TYPE_STRING  : return -1;
+    case FieldDescriptor::TYPE_BYTES   : return -1;
+    case FieldDescriptor::TYPE_GROUP   : return -1;
+    case FieldDescriptor::TYPE_MESSAGE : return -1;
+
+    // No default because we want the compiler to complain if any new
+    // types are added.
+  }
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return -1;
+}
+
+string DefaultValue(const FieldDescriptor* field) {
+  switch (field->cpp_type()) {
+    case FieldDescriptor::CPPTYPE_INT32:
+      return SimpleItoa(field->default_value_int32());
+    case FieldDescriptor::CPPTYPE_UINT32:
+      return SimpleItoa(field->default_value_uint32()) + "u";
+    case FieldDescriptor::CPPTYPE_INT64:
+      return "GOOGLE_LONGLONG(" + SimpleItoa(field->default_value_int64()) + ")";
+    case FieldDescriptor::CPPTYPE_UINT64:
+      return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")";
+    case FieldDescriptor::CPPTYPE_DOUBLE:
+      return SimpleDtoa(field->default_value_double());
+    case FieldDescriptor::CPPTYPE_FLOAT:
+      return SimpleFtoa(field->default_value_float());
+    case FieldDescriptor::CPPTYPE_BOOL:
+      return field->default_value_bool() ? "true" : "false";
+
+    case FieldDescriptor::CPPTYPE_ENUM:
+    case FieldDescriptor::CPPTYPE_STRING:
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      GOOGLE_LOG(FATAL) << "Shouldn't get here.";
+      return "";
+  }
+  // Can't actually get here; make compiler happy.  (We could add a default
+  // case above but then we wouldn't get the nice compiler warning when a
+  // new type is added.)
+  return "";
+}
+
+// TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
+//   repeat code between this and the other field types.
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+                           map<string, string>* variables) {
+  (*variables)["name"] = FieldName(descriptor);
+  (*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type());
+  (*variables)["default"] = DefaultValue(descriptor);
+  (*variables)["index"] = SimpleItoa(descriptor->index());
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
+  (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
+  (*variables)["tag_size"] = SimpleItoa(
+    WireFormat::TagSize(descriptor->number(), descriptor->type()));
+
+  int fixed_size = FixedSize(descriptor->type());
+  if (fixed_size != -1) {
+    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+  }
+}
+
+}  // namespace
+
+// ===================================================================
+
+PrimitiveFieldGenerator::
+PrimitiveFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, &variables_);
+}
+
+PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+
+void PrimitiveFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_, "$type$ $name$_;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $name$() const;\n"
+    "inline void set_$name$($type$ value);\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $classname$::$name$() const {\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline void $classname$::set_$name$($type$ value) {\n"
+    "  _set_bit($index$);\n"
+    "  $name$_ = value;\n"
+    "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_, "set_$name$(from.$name$());\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateInitializer(io::Printer* printer) const {
+  printer->Print(variables_, ",\n$name$_($default$)");
+}
+
+void PrimitiveFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(\n"
+    "      input, &$name$_));\n"
+    "_set_bit($index$);\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
+      "$number$, this->$name$(), output));\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  int fixed_size = FixedSize(descriptor_->type());
+  if (fixed_size == -1) {
+    printer->Print(variables_,
+      "total_size += $tag_size$ +\n"
+      "  ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
+      "    this->$name$());\n");
+  } else {
+    printer->Print(variables_,
+      "total_size += $tag_size$ + $fixed_size$;\n");
+  }
+}
+
+// ===================================================================
+
+RepeatedPrimitiveFieldGenerator::
+RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, &variables_);
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+void RepeatedPrimitiveFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "::google::protobuf::RepeatedField< $type$ > $name$_;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedField< $type$ >& $name$() const;\n"
+    "inline ::google::protobuf::RepeatedField< $type$ >* mutable_$name$();\n"
+    "inline $type$ $name$(int index) const;\n"
+    "inline void set_$name$(int index, $type$ value);\n"
+    "inline void add_$name$($type$ value);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
+    "$classname$::$name$() const {\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline ::google::protobuf::RepeatedField< $type$ >*\n"
+    "$classname$::mutable_$name$() {\n"
+    "  return &$name$_;\n"
+    "}\n"
+    "inline $type$ $classname$::$name$(int index) const {\n"
+    "  return $name$_.Get(index);\n"
+    "}\n"
+    "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+    "  $name$_.Set(index, value);\n"
+    "}\n"
+    "inline void $classname$::add_$name$($type$ value) {\n"
+    "  $name$_.Add(value);\n"
+    "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateInitializer(io::Printer* printer) const {
+  // Not needed for repeated fields.
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$type$ value;\n"
+    "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(input, &value));\n"
+    "add_$name$(value);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
+      "$number$, this->$name$(i), output));\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  int fixed_size = FixedSize(descriptor_->type());
+  if (fixed_size == -1) {
+    printer->Print(variables_,
+      "total_size += $tag_size$ * $name$_size();\n"
+      "for (int i = 0; i < $name$_size(); i++) {\n"
+      "  total_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
+      "    this->$name$(i));\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "total_size += ($tag_size$ + $fixed_size$) * $name$_size();\n");
+  }
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
new file mode 100644
index 0000000..832b241
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class PrimitiveFieldGenerator : public FieldGenerator {
+ public:
+  explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+  ~PrimitiveFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GeneratePrivateMembers(io::Printer* printer) const;
+  void GenerateAccessorDeclarations(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateInitializer(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
+};
+
+class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+  ~RepeatedPrimitiveFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GeneratePrivateMembers(io::Printer* printer) const;
+  void GenerateAccessorDeclarations(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateInitializer(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_service.cc b/src/google/protobuf/compiler/cpp/cpp_service.cc
new file mode 100644
index 0000000..124f3b4
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_service.cc
@@ -0,0 +1,318 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_service.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
+                                   const string& dllexport_decl)
+  : descriptor_(descriptor) {
+  vars_["classname"] = descriptor_->name();
+  vars_["full_name"] = descriptor_->full_name();
+  if (dllexport_decl.empty()) {
+    vars_["dllexport"] = "";
+  } else {
+    vars_["dllexport"] = dllexport_decl + " ";
+  }
+}
+
+ServiceGenerator::~ServiceGenerator() {}
+
+void ServiceGenerator::GenerateDeclarations(io::Printer* printer) {
+  // Forward-declare the stub type.
+  printer->Print(vars_,
+    "class $classname$_Stub;\n"
+    "\n");
+
+  GenerateInterface(printer);
+  GenerateStubDefinition(printer);
+}
+
+void ServiceGenerator::GenerateInterface(io::Printer* printer) {
+  printer->Print(vars_,
+    "class $dllexport$$classname$ : public ::google::protobuf::Service {\n"
+    " protected:\n"
+    "  // This class should be treated as an abstract interface.\n"
+    "  inline $classname$() {};\n"
+    " public:\n"
+    "  virtual ~$classname$();\n");
+  printer->Indent();
+
+  printer->Print(vars_,
+    "\n"
+    "typedef $classname$_Stub Stub;\n"
+    "\n"
+    "static const ::google::protobuf::ServiceDescriptor* descriptor();\n"
+    "\n");
+
+  GenerateMethodSignatures(VIRTUAL, printer);
+
+  printer->Print(
+    "\n"
+    "// implements Service ----------------------------------------------\n"
+    "\n"
+    "const ::google::protobuf::ServiceDescriptor* GetDescriptor();\n"
+    "void CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
+    "                ::google::protobuf::RpcController* controller,\n"
+    "                const ::google::protobuf::Message* request,\n"
+    "                ::google::protobuf::Message* response,\n"
+    "                ::google::protobuf::Closure* done);\n"
+    "const ::google::protobuf::Message& GetRequestPrototype(\n"
+    "  const ::google::protobuf::MethodDescriptor* method) const;\n"
+    "const ::google::protobuf::Message& GetResponsePrototype(\n"
+    "  const ::google::protobuf::MethodDescriptor* method) const;\n");
+
+  printer->Outdent();
+  printer->Print(vars_,
+    "\n"
+    " private:\n"
+    "  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n"
+    "};\n"
+    "\n");
+}
+
+void ServiceGenerator::GenerateStubDefinition(io::Printer* printer) {
+  printer->Print(vars_,
+    "class $dllexport$$classname$_Stub : public $classname$ {\n"
+    " public:\n");
+
+  printer->Indent();
+
+  printer->Print(vars_,
+    "$classname$_Stub(::google::protobuf::RpcChannel* channel);\n"
+    "$classname$_Stub(::google::protobuf::RpcChannel* channel,\n"
+    "                 ::google::protobuf::Service::ChannelOwnership ownership);\n"
+    "~$classname$_Stub();\n"
+    "\n"
+    "inline ::google::protobuf::RpcChannel* channel() { return channel_; }\n"
+    "\n"
+    "// implements $classname$ ------------------------------------------\n"
+    "\n");
+
+  GenerateMethodSignatures(NON_VIRTUAL, printer);
+
+  printer->Outdent();
+  printer->Print(vars_,
+    " private:\n"
+    "  ::google::protobuf::RpcChannel* channel_;\n"
+    "  bool owns_channel_;\n"
+    "  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$_Stub);\n"
+    "};\n"
+    "\n");
+}
+
+void ServiceGenerator::GenerateMethodSignatures(
+    VirtualOrNon virtual_or_non, io::Printer* printer) {
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    map<string, string> sub_vars;
+    sub_vars["name"] = method->name();
+    sub_vars["input_type"] = ClassName(method->input_type(), true);
+    sub_vars["output_type"] = ClassName(method->output_type(), true);
+    sub_vars["virtual"] = virtual_or_non == VIRTUAL ? "virtual " : "";
+
+    printer->Print(sub_vars,
+      "$virtual$void $name$(::google::protobuf::RpcController* controller,\n"
+      "                     const $input_type$* request,\n"
+      "                     $output_type$* response,\n"
+      "                     ::google::protobuf::Closure* done);\n");
+  }
+}
+
+// ===================================================================
+
+void ServiceGenerator::GenerateDescriptorInitializer(
+    io::Printer* printer, int index) {
+  map<string, string> vars;
+  vars["classname"] = descriptor_->name();
+  vars["index"] = SimpleItoa(index);
+
+  printer->Print(vars,
+    "$classname$_descriptor_ = file->service($index$);\n");
+}
+
+// ===================================================================
+
+void ServiceGenerator::GenerateImplementation(io::Printer* printer) {
+  printer->Print(vars_,
+    "$classname$::~$classname$() {}\n"
+    "\n"
+    "const ::google::protobuf::ServiceDescriptor* $classname$::descriptor() {\n"
+    "  return $classname$_descriptor_;\n"
+    "}\n"
+    "\n"
+    "const ::google::protobuf::ServiceDescriptor* $classname$::GetDescriptor() {\n"
+    "  return $classname$_descriptor_;\n"
+    "}\n"
+    "\n");
+
+  // Generate methods of the interface.
+  GenerateNotImplementedMethods(printer);
+  GenerateCallMethod(printer);
+  GenerateGetPrototype(REQUEST, printer);
+  GenerateGetPrototype(RESPONSE, printer);
+
+  // Generate stub implementation.
+  printer->Print(vars_,
+    "$classname$_Stub::$classname$_Stub(::google::protobuf::RpcChannel* channel)\n"
+    "  : channel_(channel), owns_channel_(false) {}\n"
+    "$classname$_Stub::$classname$_Stub(\n"
+    "    ::google::protobuf::RpcChannel* channel,\n"
+    "    ::google::protobuf::Service::ChannelOwnership ownership)\n"
+    "  : channel_(channel),\n"
+    "    owns_channel_(ownership == ::google::protobuf::Service::STUB_OWNS_CHANNEL) {}\n"
+    "$classname$_Stub::~$classname$_Stub() {\n"
+    "  if (owns_channel_) delete channel_;\n"
+    "}\n"
+    "\n");
+
+  GenerateStubMethods(printer);
+}
+
+void ServiceGenerator::GenerateNotImplementedMethods(io::Printer* printer) {
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    map<string, string> sub_vars;
+    sub_vars["classname"] = descriptor_->name();
+    sub_vars["name"] = method->name();
+    sub_vars["index"] = SimpleItoa(i);
+    sub_vars["input_type"] = ClassName(method->input_type(), true);
+    sub_vars["output_type"] = ClassName(method->output_type(), true);
+
+    printer->Print(sub_vars,
+      "void $classname$::$name$(::google::protobuf::RpcController* controller,\n"
+      "                         const $input_type$* request,\n"
+      "                         $output_type$* response,\n"
+      "                         ::google::protobuf::Closure* done) {\n"
+      "  controller->SetFailed(\"Method $name$() not implemented.\");\n"
+      "  done->Run();\n"
+      "}\n"
+      "\n");
+  }
+}
+
+void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
+  printer->Print(vars_,
+    "void $classname$::CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
+    "                             ::google::protobuf::RpcController* controller,\n"
+    "                             const ::google::protobuf::Message* request,\n"
+    "                             ::google::protobuf::Message* response,\n"
+    "                             ::google::protobuf::Closure* done) {\n"
+    "  GOOGLE_DCHECK_EQ(method->service(), $classname$_descriptor_);\n"
+    "  switch(method->index()) {\n");
+
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    map<string, string> sub_vars;
+    sub_vars["name"] = method->name();
+    sub_vars["index"] = SimpleItoa(i);
+    sub_vars["input_type"] = ClassName(method->input_type(), true);
+    sub_vars["output_type"] = ClassName(method->output_type(), true);
+
+    // Note:  ::google::protobuf::down_cast does not work here because it only works on pointers,
+    //   not references.
+    printer->Print(sub_vars,
+      "    case $index$:\n"
+      "      $name$(controller,\n"
+      "             ::google::protobuf::down_cast<const $input_type$*>(request),\n"
+      "             ::google::protobuf::down_cast< $output_type$*>(response),\n"
+      "             done);\n"
+      "      break;\n");
+  }
+
+  printer->Print(vars_,
+    "    default:\n"
+    "      GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
+    "      break;\n"
+    "  }\n"
+    "}\n"
+    "\n");
+}
+
+void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
+                                            io::Printer* printer) {
+  if (which == REQUEST) {
+    printer->Print(vars_,
+      "const ::google::protobuf::Message& $classname$::GetRequestPrototype(\n");
+  } else {
+    printer->Print(vars_,
+      "const ::google::protobuf::Message& $classname$::GetResponsePrototype(\n");
+  }
+
+  printer->Print(vars_,
+    "    const ::google::protobuf::MethodDescriptor* method) const {\n"
+    "  GOOGLE_DCHECK_EQ(method->service(), $classname$_descriptor_);\n"
+    "  switch(method->index()) {\n");
+
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    const Descriptor* type =
+      (which == REQUEST) ? method->input_type() : method->output_type();
+
+    map<string, string> sub_vars;
+    sub_vars["index"] = SimpleItoa(i);
+    sub_vars["type"] = ClassName(type, true);
+
+    printer->Print(sub_vars,
+      "    case $index$:\n"
+      "      return $type$::default_instance();\n");
+  }
+
+  printer->Print(vars_,
+    "    default:\n"
+    "      GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
+    "      return *reinterpret_cast< ::google::protobuf::Message*>(NULL);\n"
+    "  }\n"
+    "}\n"
+    "\n");
+}
+
+void ServiceGenerator::GenerateStubMethods(io::Printer* printer) {
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    map<string, string> sub_vars;
+    sub_vars["classname"] = descriptor_->name();
+    sub_vars["name"] = method->name();
+    sub_vars["index"] = SimpleItoa(i);
+    sub_vars["input_type"] = ClassName(method->input_type(), true);
+    sub_vars["output_type"] = ClassName(method->output_type(), true);
+
+    printer->Print(sub_vars,
+      "void $classname$_Stub::$name$(::google::protobuf::RpcController* controller,\n"
+      "                              const $input_type$* request,\n"
+      "                              $output_type$* response,\n"
+      "                              ::google::protobuf::Closure* done) {\n"
+      "  channel_->CallMethod($classname$_descriptor_->method($index$),\n"
+      "                       controller, request, response, done);\n"
+      "}\n");
+  }
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_service.h b/src/google/protobuf/compiler/cpp/cpp_service.h
new file mode 100644
index 0000000..bccb64e
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_service.h
@@ -0,0 +1,104 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class ServiceGenerator {
+ public:
+  // See generator.cc for the meaning of dllexport_decl.
+  explicit ServiceGenerator(const ServiceDescriptor* descriptor,
+                            const string& dllexport_decl);
+  ~ServiceGenerator();
+
+  // Header stuff.
+
+  // Generate the class definitions for the service's interface and the
+  // stub implementation.
+  void GenerateDeclarations(io::Printer* printer);
+
+  // Source file stuff.
+
+  // Generate code that initializes the global variable storing the service's
+  // descriptor.
+  void GenerateDescriptorInitializer(io::Printer* printer, int index);
+
+  // Generate implementations of everything declared by GenerateDeclarations().
+  void GenerateImplementation(io::Printer* printer);
+
+ private:
+  enum RequestOrResponse { REQUEST, RESPONSE };
+  enum VirtualOrNon { VIRTUAL, NON_VIRTUAL };
+
+  // Header stuff.
+
+  // Generate the service abstract interface.
+  void GenerateInterface(io::Printer* printer);
+
+  // Generate the stub class definition.
+  void GenerateStubDefinition(io::Printer* printer);
+
+  // Prints signatures for all methods in the
+  void GenerateMethodSignatures(VirtualOrNon virtual_or_non,
+                                io::Printer* printer);
+
+  // Source file stuff.
+
+  // Generate the default implementations of the service methods, which
+  // produce a "not implemented" error.
+  void GenerateNotImplementedMethods(io::Printer* printer);
+
+  // Generate the CallMethod() method of the service.
+  void GenerateCallMethod(io::Printer* printer);
+
+  // Generate the Get{Request,Response}Prototype() methods.
+  void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer);
+
+  // Generate the stub's implementations of the service methods.
+  void GenerateStubMethods(io::Printer* printer);
+
+  const ServiceDescriptor* descriptor_;
+  map<string, string> vars_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
new file mode 100644
index 0000000..de59ac8
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -0,0 +1,336 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_string_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format_inl.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+
+namespace {
+
+// TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
+//   repeat code between this and the other field types.
+void SetStringVariables(const FieldDescriptor* descriptor,
+                        map<string, string>* variables) {
+  (*variables)["name"] = FieldName(descriptor);
+  (*variables)["default"] =
+    "\"" + CEscape(descriptor->default_value_string()) + "\"";
+  (*variables)["index"] = SimpleItoa(descriptor->index());
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
+  (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
+  (*variables)["tag_size"] = SimpleItoa(
+    WireFormat::TagSize(descriptor->number(), descriptor->type()));
+}
+
+}  // namespace
+
+// ===================================================================
+
+StringFieldGenerator::
+StringFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetStringVariables(descriptor, &variables_);
+}
+
+StringFieldGenerator::~StringFieldGenerator() {}
+
+void StringFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "::std::string* $name$_;\n"
+    "static const ::std::string _default_$name$_;\n");
+}
+
+void StringFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+  // If we're using StringFieldGenerator for a field with a ctype, it's
+  // because that ctype isn't actually implemented.  In particular, this is
+  // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
+  // We aren't releasing Cord because it has too many Google-specific
+  // dependencies and we aren't releasing StringPiece because it's hardly
+  // useful outside of Google and because it would get confusing to have
+  // multiple instances of the StringPiece class in different libraries (PCRE
+  // already includes it for their C++ bindings, which came from Google).
+  //
+  // In any case, we make all the accessors private while still actually
+  // using a string to represent the field internally.  This way, we can
+  // guarantee that if we do ever implement the ctype, it won't break any
+  // existing users who might be -- for whatever reason -- already using .proto
+  // files that applied the ctype.  The field can still be accessed via the
+  // reflection interface since the reflection interface is independent of
+  // the string's underlying representation.
+  if (descriptor_->options().has_ctype()) {
+    printer->Outdent();
+    printer->Print(
+      " private:\n"
+      "  // Hidden due to unknown ctype option.\n");
+    printer->Indent();
+  }
+
+  printer->Print(variables_,
+    "inline const ::std::string& $name$() const;\n"
+    "inline void set_$name$(const ::std::string& value);\n"
+    "inline void set_$name$(const char* value);\n");
+
+  printer->Print(variables_,
+    "inline ::std::string* mutable_$name$();\n");
+
+  if (descriptor_->options().has_ctype()) {
+    printer->Outdent();
+    printer->Print(" public:\n");
+    printer->Indent();
+  }
+}
+
+void StringFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const ::std::string& $classname$::$name$() const {\n"
+    "  return *$name$_;\n"
+    "}\n"
+    "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+    "  _set_bit($index$);\n"
+    "  if ($name$_ == &_default_$name$_) {\n"
+    "    $name$_ = new ::std::string;\n"
+    "  }\n"
+    "  $name$_->assign(value);\n"
+    "}\n"
+    "inline void $classname$::set_$name$(const char* value) {\n"
+    "  _set_bit($index$);\n"
+    "  if ($name$_ == &_default_$name$_) {\n"
+    "    $name$_ = new ::std::string;\n"
+    "  }\n"
+    "  $name$_->assign(value);\n"
+    "}\n");
+  printer->Print(variables_,
+    "inline ::std::string* $classname$::mutable_$name$() {\n"
+    "  _set_bit($index$);\n"
+    "  if ($name$_ == &_default_$name$_) {\n");
+  if (descriptor_->has_default_value()) {
+    printer->Print(variables_,
+      "    $name$_ = new ::std::string(_default_$name$_);\n");
+  } else {
+    printer->Print(variables_,
+      "    $name$_ = new ::std::string;\n");
+  }
+  printer->Print(variables_,
+    "  }\n"
+    "  return $name$_;\n"
+    "}\n");
+}
+
+void StringFieldGenerator::
+GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
+  if (descriptor_->has_default_value()) {
+    printer->Print(variables_,
+      "const ::std::string $classname$::_default_$name$_($default$);");
+  } else {
+    printer->Print(variables_,
+      "const ::std::string $classname$::_default_$name$_;");
+  }
+}
+
+void StringFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  if (descriptor_->has_default_value()) {
+    printer->Print(variables_,
+      "if ($name$_ != &_default_$name$_) {\n"
+      "  $name$_->assign(_default_$name$_);\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "if ($name$_ != &_default_$name$_) {\n"
+      "  $name$_->clear();\n"
+      "}\n");
+  }
+}
+
+void StringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_, "set_$name$(from.$name$());\n");
+}
+
+void StringFieldGenerator::
+GenerateInitializer(io::Printer* printer) const {
+  printer->Print(variables_,
+    ",\n$name$_(const_cast< ::std::string*>(&_default_$name$_))");
+}
+
+void StringFieldGenerator::
+GenerateDestructorCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($name$_ != &_default_$name$_) {\n"
+    "  delete $name$_;\n"
+    "}\n");
+}
+
+void StringFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$("
+      "input, mutable_$name$()));\n");
+}
+
+void StringFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
+      "$number$, this->$name$(), output));\n");
+}
+
+void StringFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ +\n"
+    "  ::google::protobuf::internal::WireFormat::$declared_type$Size(this->$name$());\n");
+}
+
+// ===================================================================
+
+RepeatedStringFieldGenerator::
+RepeatedStringFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetStringVariables(descriptor, &variables_);
+}
+
+RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
+
+void RepeatedStringFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "::google::protobuf::RepeatedPtrField< ::std::string> $name$_;\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+  // See comment above about unknown ctypes.
+  if (descriptor_->options().has_ctype()) {
+    printer->Outdent();
+    printer->Print(
+      " private:\n"
+      "  // Hidden due to unknown ctype option.\n");
+    printer->Indent();
+  }
+
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const;\n"
+    "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$();\n"
+    "inline const ::std::string& $name$(int index) const;\n"
+    "inline ::std::string* mutable_$name$(int index);\n"
+    "inline void set_$name$(int index, const ::std::string& value);\n"
+    "inline void set_$name$(int index, const char* value);\n"
+    "inline ::std::string* add_$name$();\n"
+    "inline void add_$name$(const ::std::string& value);\n"
+    "inline void add_$name$(const char* value);\n");
+
+  if (descriptor_->options().has_ctype()) {
+    printer->Outdent();
+    printer->Print(" public:\n");
+    printer->Indent();
+  }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
+    "$classname$::$name$() const {\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
+    "$classname$::mutable_$name$() {\n"
+    "  return &$name$_;\n"
+    "}\n"
+    "inline const ::std::string& $classname$::$name$(int index) const {\n"
+    "  return $name$_.Get(index);\n"
+    "}\n"
+    "inline ::std::string* $classname$::mutable_$name$(int index) {\n"
+    "  return $name$_.Mutable(index);\n"
+    "}\n"
+    "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
+    "  $name$_.Mutable(index)->assign(value);\n"
+    "}\n"
+    "inline void $classname$::set_$name$(int index, const char* value) {\n"
+    "  $name$_.Mutable(index)->assign(value);\n"
+    "}\n"
+    "inline ::std::string* $classname$::add_$name$() {\n"
+    "  return $name$_.Add();\n"
+    "}\n"
+    "inline void $classname$::add_$name$(const ::std::string& value) {\n"
+    "  $name$_.Add()->assign(value);\n"
+    "}\n"
+    "inline void $classname$::add_$name$(const char* value) {\n"
+    "  $name$_.Add()->assign(value);\n"
+    "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateInitializer(io::Printer* printer) const {
+  // Not needed for repeated fields.
+}
+
+void RepeatedStringFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(\n"
+    "     input, add_$name$()));\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
+      "$number$, this->$name$(i), output));\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ * $name$_size();\n"
+    "for (int i = 0; i < $name$_size(); i++) {\n"
+    "  total_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
+    "    this->$name$(i));\n"
+    "}\n");
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h
new file mode 100644
index 0000000..44ffd18
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -0,0 +1,86 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class StringFieldGenerator : public FieldGenerator {
+ public:
+  explicit StringFieldGenerator(const FieldDescriptor* descriptor);
+  ~StringFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GeneratePrivateMembers(io::Printer* printer) const;
+  void GenerateAccessorDeclarations(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateInitializer(io::Printer* printer) const;
+  void GenerateDestructorCode(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator);
+};
+
+class RepeatedStringFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor);
+  ~RepeatedStringFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GeneratePrivateMembers(io::Printer* printer) const;
+  void GenerateAccessorDeclarations(io::Printer* printer) const;
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateInitializer(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
new file mode 100644
index 0000000..ee0499b
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
@@ -0,0 +1,87 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file tests that various identifiers work as field and type names even
+// though the same identifiers are used internally by the C++ code generator.
+
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+package protobuf_unittest;
+
+// Test that fields can have names like "input" and "i" which are also used
+// internally by the code generator for local variables.
+message TestConflictingSymbolNames {
+  message BuildDescriptors {}
+  message TypeTraits {}
+
+  optional int32 input = 1;
+  optional int32 output = 2;
+  optional string length = 3;
+  repeated int32 i = 4;
+  repeated string new_element = 5 [ctype=STRING_PIECE];
+  optional int32 total_size = 6;
+  optional int32 tag = 7;
+
+  optional int32 source = 8;
+  optional int32 value = 9;
+  optional int32 file = 10;
+  optional int32 from = 11;
+  optional int32 handle_uninterpreted = 12;
+  repeated int32 index = 13;
+  optional int32 controller = 14;
+  optional int32 already_here = 15;
+
+  optional uint32 uint32 = 16;
+  optional uint64 uint64 = 17;
+  optional string string = 18;
+  optional int32 memset = 19;
+  optional int32 int32 = 20;
+  optional int64 int64 = 21;
+
+  optional uint32 cached_size = 22;
+  optional uint32 extensions = 23;
+  optional uint32 bit = 24;
+  optional uint32 bits = 25;
+  optional uint32 offsets = 26;
+  optional uint32 reflection = 27;
+
+  message Cord {}
+  optional string some_cord = 28 [ctype=CORD];
+
+  message StringPiece {}
+  optional string some_string_piece = 29 [ctype=STRING_PIECE];
+
+  // Some keywords.
+  optional uint32 int = 30;
+  optional uint32 friend = 31;
+
+  // The generator used to #define a macro called "DO" inside the .cc file.
+  message DO {}
+  optional DO do = 32;
+
+  extensions 1000 to max;
+}
+
+message DummyMessage {}
+
+service TestConflictingMethodNames {
+  rpc Closure(DummyMessage) returns (DummyMessage);
+}
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
new file mode 100644
index 0000000..8253242
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -0,0 +1,835 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// To test the code generator, we actually use it to generate code for
+// google/protobuf/unittest.proto, then test that.  This means that we
+// are actually testing the parser and other parts of the system at the same
+// time, and that problems in the generator may show up as compile-time errors
+// rather than unittest failures, which may be surprising.  However, testing
+// the output of the C++ generator directly would be very hard.  We can't very
+// well just check it against golden files since those files would have to be
+// updated for any small change; such a test would be very brittle and probably
+// not very helpful.  What we really want to test is that the code compiles
+// correctly and produces the interfaces we expect, which is why this test
+// is written this way.
+
+#include <vector>
+
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_optimize_for.pb.h>
+#include <google/protobuf/unittest_embed_optimize_for.pb.h>
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h>
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/dynamic_message.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+
+class MockErrorCollector : public MultiFileErrorCollector {
+ public:
+  MockErrorCollector() {}
+  ~MockErrorCollector() {}
+
+  string text_;
+
+  // implements ErrorCollector ---------------------------------------
+  void AddError(const string& filename, int line, int column,
+                const string& message) {
+    strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n",
+                                 filename, line, column, message);
+  }
+};
+
+// Test that generated code has proper descriptors:
+// Parse a descriptor directly (using google::protobuf::compiler::Importer) and
+// compare it to the one that was produced by generated code.
+TEST(GeneratedDescriptorTest, IdenticalDescriptors) {
+  const FileDescriptor* generated_descriptor =
+    unittest::TestAllTypes::descriptor()->file();
+
+  // Set up the Importer.
+  MockErrorCollector error_collector;
+  DiskSourceTree source_tree;
+  source_tree.MapPath("", TestSourceDir());
+  Importer importer(&source_tree, &error_collector);
+
+  // Import (parse) unittest.proto.
+  const FileDescriptor* parsed_descriptor =
+    importer.Import("google/protobuf/unittest.proto");
+  EXPECT_EQ("", error_collector.text_);
+  ASSERT_TRUE(parsed_descriptor != NULL);
+
+  // Test that descriptors are generated correctly by converting them to
+  // FileDescriptorProtos and comparing.
+  FileDescriptorProto generated_decsriptor_proto, parsed_descriptor_proto;
+  generated_descriptor->CopyTo(&generated_decsriptor_proto);
+  parsed_descriptor->CopyTo(&parsed_descriptor_proto);
+
+  EXPECT_EQ(parsed_descriptor_proto.DebugString(),
+            generated_decsriptor_proto.DebugString());
+}
+
+// ===================================================================
+
+TEST(GeneratedMessageTest, Defaults) {
+  // Check that all default values are set correctly in the initial message.
+  unittest::TestAllTypes message;
+
+  TestUtil::ExpectClear(message);
+
+  // 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(),
+            &message.optionalgroup());
+  EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &message.optional_nested_message());
+  EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
+            &message.optional_foreign_message());
+  EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
+            &message.optional_import_message());
+}
+
+TEST(GeneratedMessageTest, Accessors) {
+  // Set every field to a unique value then go back and check all those
+  // values.
+  unittest::TestAllTypes message;
+
+  TestUtil::SetAllFields(&message);
+  TestUtil::ExpectAllFieldsSet(message);
+
+  TestUtil::ModifyRepeatedFields(&message);
+  TestUtil::ExpectRepeatedFieldsModified(message);
+}
+
+TEST(GeneratedMessageTest, MutableStringDefault) {
+  // mutable_foo() for a string should return a string initialized to its
+  // default value.
+  unittest::TestAllTypes message;
+
+  EXPECT_EQ("hello", *message.mutable_default_string());
+
+  // Note that the first time we call mutable_foo(), we get a newly-allocated
+  // string, but if we clear it and call it again, we get the same object again.
+  // We should verify that it has its default value in both cases.
+  message.set_default_string("blah");
+  message.Clear();
+
+  EXPECT_EQ("hello", *message.mutable_default_string());
+}
+
+TEST(GeneratedMessageTest, Clear) {
+  // Set every field to a unique value, clear the message, then check that
+  // it is cleared.
+  unittest::TestAllTypes message;
+
+  TestUtil::SetAllFields(&message);
+  message.Clear();
+  TestUtil::ExpectClear(message);
+
+  // Unlike with the defaults test, we do NOT expect that requesting embedded
+  // messages will return a pointer to the default instance.  Instead, they
+  // should return the objects that were created when mutable_blah() was
+  // called.
+  EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+            &message.optionalgroup());
+  EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &message.optional_nested_message());
+  EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+            &message.optional_foreign_message());
+  EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+            &message.optional_import_message());
+}
+
+TEST(GeneratedMessageTest, ClearOneField) {
+  // Set every field to a unique value, then clear one value and insure that
+  // only that one value is cleared.
+  unittest::TestAllTypes message;
+
+  TestUtil::SetAllFields(&message);
+  int64 original_value = message.optional_int64();
+
+  // Clear the field and make sure it shows up as cleared.
+  message.clear_optional_int64();
+  EXPECT_FALSE(message.has_optional_int64());
+  EXPECT_EQ(0, message.optional_int64());
+
+  // Other adjacent fields should not be cleared.
+  EXPECT_TRUE(message.has_optional_int32());
+  EXPECT_TRUE(message.has_optional_uint32());
+
+  // Make sure if we set it again, then all fields are set.
+  message.set_optional_int64(original_value);
+  TestUtil::ExpectAllFieldsSet(message);
+}
+
+
+TEST(GeneratedMessageTest, CopyFrom) {
+  unittest::TestAllTypes message1, message2;
+  string data;
+
+  TestUtil::SetAllFields(&message1);
+  message2.CopyFrom(message1);
+  TestUtil::ExpectAllFieldsSet(message2);
+
+  // Copying from self should be a no-op.
+  message2.CopyFrom(message2);
+  TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(GeneratedMessageTest, CopyConstructor) {
+  unittest::TestAllTypes message1;
+  TestUtil::SetAllFields(&message1);
+
+  unittest::TestAllTypes message2(message1);
+  TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(GeneratedMessageTest, CopyAssignmentOperator) {
+  unittest::TestAllTypes message1;
+  TestUtil::SetAllFields(&message1);
+
+  unittest::TestAllTypes message2;
+  message2 = message1;
+  TestUtil::ExpectAllFieldsSet(message2);
+
+  // Make sure that self-assignment does something sane.
+  message2 = message2;
+  TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(GeneratedMessageTest, UpcastCopyFrom) {
+  // Test the CopyFrom method that takes in the generic const Message&
+  // parameter.
+  unittest::TestAllTypes message1, message2;
+
+  TestUtil::SetAllFields(&message1);
+
+  const Message* source = implicit_cast<const Message*>(&message1);
+  message2.CopyFrom(*source);
+
+  TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(GeneratedMessageTest, DynamicMessageCopyFrom) {
+  // Test copying from a DynamicMessage, which must fall back to using
+  // reflection.
+  unittest::TestAllTypes message2;
+
+  // Construct a new version of the dynamic message via the factory.
+  DynamicMessageFactory factory;
+  scoped_ptr<Message> message1;
+  message1.reset(factory.GetPrototype(
+                     unittest::TestAllTypes::descriptor())->New());
+
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllTypes::descriptor());
+  reflection_tester.SetAllFieldsViaReflection(message1->GetReflection());
+
+  message2.CopyFrom(*message1);
+
+  TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(GeneratedMessageTest, NonEmptyMergeFrom) {
+  // Test merging with a non-empty message. Code is a modified form
+  // of that found in google/protobuf/reflection_ops_unittest.cc.
+  unittest::TestAllTypes message1, message2;
+
+  TestUtil::SetAllFields(&message1);
+
+  // This field will test merging into an empty spot.
+  message2.set_optional_int32(message1.optional_int32());
+  message1.clear_optional_int32();
+
+  // This tests overwriting.
+  message2.set_optional_string(message1.optional_string());
+  message1.set_optional_string("something else");
+
+  // This tests concatenating.
+  message2.add_repeated_int32(message1.repeated_int32(1));
+  int32 i = message1.repeated_int32(0);
+  message1.clear_repeated_int32();
+  message1.add_repeated_int32(i);
+
+  message1.MergeFrom(message2);
+
+  TestUtil::ExpectAllFieldsSet(message1);
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST(GeneratedMessageTest, MergeFromSelf) {
+  unittest::TestAllTypes message;
+  EXPECT_DEATH(message.MergeFrom(message), "&from");
+  EXPECT_DEATH(message.MergeFrom(implicit_cast<const Message&>(message)),
+               "&from");
+}
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+TEST(GeneratedMessageTest, Serialization) {
+  unittest::TestAllTypes message1, message2;
+  string data;
+
+  TestUtil::SetAllFields(&message1);
+  message1.SerializeToString(&data);
+  EXPECT_TRUE(message2.ParseFromString(data));
+  TestUtil::ExpectAllFieldsSet(message2);
+
+}
+
+
+TEST(GeneratedMessageTest, Required) {
+  // Test that IsInitialized() returns false if required fields are missing.
+  unittest::TestRequired message;
+
+  EXPECT_FALSE(message.IsInitialized());
+  message.set_a(1);
+  EXPECT_FALSE(message.IsInitialized());
+  message.set_b(2);
+  EXPECT_FALSE(message.IsInitialized());
+  message.set_c(3);
+  EXPECT_TRUE(message.IsInitialized());
+}
+
+TEST(GeneratedMessageTest, RequiredForeign) {
+  // Test that IsInitialized() returns false if required fields in nested
+  // messages are missing.
+  unittest::TestRequiredForeign message;
+
+  EXPECT_TRUE(message.IsInitialized());
+
+  message.mutable_optional_message();
+  EXPECT_FALSE(message.IsInitialized());
+
+  message.mutable_optional_message()->set_a(1);
+  message.mutable_optional_message()->set_b(2);
+  message.mutable_optional_message()->set_c(3);
+  EXPECT_TRUE(message.IsInitialized());
+
+  message.add_repeated_message();
+  EXPECT_FALSE(message.IsInitialized());
+
+  message.mutable_repeated_message(0)->set_a(1);
+  message.mutable_repeated_message(0)->set_b(2);
+  message.mutable_repeated_message(0)->set_c(3);
+  EXPECT_TRUE(message.IsInitialized());
+}
+
+TEST(GeneratedMessageTest, ForeignNested) {
+  // Test that TestAllTypes::NestedMessage can be embedded directly into
+  // another message.
+  unittest::TestForeignNested message;
+
+  // If this compiles and runs without crashing, it must work.  We have
+  // nothing more to test.
+  unittest::TestAllTypes::NestedMessage* nested =
+    message.mutable_foreign_nested();
+  nested->set_bb(1);
+}
+
+TEST(GeneratedMessageTest, ReallyLargeTagNumber) {
+  // Test that really large tag numbers don't break anything.
+  unittest::TestReallyLargeTagNumber message1, message2;
+  string data;
+
+  // For the most part, if this compiles and runs then we're probably good.
+  // (The most likely cause for failure would be if something were attempting
+  // to allocate a lookup table of some sort using tag numbers as the index.)
+  // We'll try serializing just for fun.
+  message1.set_a(1234);
+  message1.set_bb(5678);
+  message1.SerializeToString(&data);
+  EXPECT_TRUE(message2.ParseFromString(data));
+  EXPECT_EQ(1234, message2.a());
+  EXPECT_EQ(5678, message2.bb());
+}
+
+TEST(GeneratedMessageTest, MutualRecursion) {
+  // Test that mutually-recursive message types work.
+  unittest::TestMutualRecursionA message;
+  unittest::TestMutualRecursionA* nested = message.mutable_bb()->mutable_a();
+  unittest::TestMutualRecursionA* nested2 = nested->mutable_bb()->mutable_a();
+
+  // Again, if the above compiles and runs, that's all we really have to
+  // test, but just for run we'll check that the system didn't somehow come
+  // up with a pointer loop...
+  EXPECT_NE(&message, nested);
+  EXPECT_NE(&message, nested2);
+  EXPECT_NE(nested, nested2);
+}
+
+TEST(GeneratedMessageTest, CamelCaseFieldNames) {
+  // This test is mainly checking that the following compiles, which verifies
+  // that the field names were coerced to lower-case.
+  //
+  // Protocol buffers standard style is to use lowercase-with-underscores for
+  // field names.  Some old proto1 .protos unfortunately used camel-case field
+  // names.  In proto1, these names were forced to lower-case.  So, we do the
+  // same thing in proto2.
+
+  unittest::TestCamelCaseFieldNames message;
+
+  message.set_primitivefield(2);
+  message.set_stringfield("foo");
+  message.set_enumfield(unittest::FOREIGN_FOO);
+  message.mutable_messagefield()->set_c(6);
+
+  message.add_repeatedprimitivefield(8);
+  message.add_repeatedstringfield("qux");
+  message.add_repeatedenumfield(unittest::FOREIGN_BAR);
+  message.add_repeatedmessagefield()->set_c(15);
+
+  EXPECT_EQ(2, message.primitivefield());
+  EXPECT_EQ("foo", message.stringfield());
+  EXPECT_EQ(unittest::FOREIGN_FOO, message.enumfield());
+  EXPECT_EQ(6, message.messagefield().c());
+
+  EXPECT_EQ(8, message.repeatedprimitivefield(0));
+  EXPECT_EQ("qux", message.repeatedstringfield(0));
+  EXPECT_EQ(unittest::FOREIGN_BAR, message.repeatedenumfield(0));
+  EXPECT_EQ(15, message.repeatedmessagefield(0).c());
+}
+
+TEST(GeneratedMessageTest, TestConflictingSymbolNames) {
+  // test_bad_identifiers.proto successfully compiled, then it works.  The
+  // following is just a token usage to insure that the code is, in fact,
+  // being compiled and linked.
+
+  protobuf_unittest::TestConflictingSymbolNames message;
+  message.set_uint32(1);
+  EXPECT_EQ(3, message.ByteSize());
+
+  message.set_friend_(5);
+  EXPECT_EQ(5, message.friend_());
+}
+
+TEST(GeneratedMessageTest, TestOptimizedForSize) {
+  // We rely on the tests in reflection_ops_unittest and wire_format_unittest
+  // to really test that reflection-based methods work.  Here we are mostly
+  // just making sure that TestOptimizedForSize actually builds and seems to
+  // function.
+
+  protobuf_unittest::TestOptimizedForSize message, message2;
+  message.set_i(1);
+  message.mutable_msg()->set_c(2);
+  message2.CopyFrom(message);
+  EXPECT_EQ(1, message2.i());
+  EXPECT_EQ(2, message2.msg().c());
+}
+
+TEST(GeneratedMessageTest, TestEmbedOptimizedForSize) {
+  // Verifies that something optimized for speed can contain something optimized
+  // for size.
+
+  protobuf_unittest::TestEmbedOptimizedForSize message, message2;
+  message.mutable_optional_message()->set_i(1);
+  message.add_repeated_message()->mutable_msg()->set_c(2);
+  string data;
+  message.SerializeToString(&data);
+  ASSERT_TRUE(message2.ParseFromString(data));
+  EXPECT_EQ(1, message2.optional_message().i());
+  EXPECT_EQ(2, message2.repeated_message(0).msg().c());
+}
+
+// ===================================================================
+
+TEST(GeneratedEnumTest, EnumValuesAsSwitchCases) {
+  // Test that our nested enum values can be used as switch cases.  This test
+  // doesn't actually do anything, the proof that it works is that it
+  // compiles.
+  int i =0;
+  unittest::TestAllTypes::NestedEnum a = unittest::TestAllTypes::BAR;
+  switch (a) {
+    case unittest::TestAllTypes::FOO:
+      i = 1;
+      break;
+    case unittest::TestAllTypes::BAR:
+      i = 2;
+      break;
+    case unittest::TestAllTypes::BAZ:
+      i = 3;
+      break;
+    // no default case:  We want to make sure the compiler recognizes that
+    //   all cases are covered.  (GCC warns if you do not cover all cases of
+    //   an enum in a switch.)
+  }
+
+  // Token check just for fun.
+  EXPECT_EQ(2, i);
+}
+
+TEST(GeneratedEnumTest, IsValidValue) {
+  // Test enum IsValidValue.
+  EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(1));
+  EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(2));
+  EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(3));
+
+  EXPECT_FALSE(unittest::TestAllTypes::NestedEnum_IsValid(0));
+  EXPECT_FALSE(unittest::TestAllTypes::NestedEnum_IsValid(4));
+
+  // Make sure it also works when there are dups.
+  EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(1));
+  EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(2));
+  EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(3));
+
+  EXPECT_FALSE(unittest::TestEnumWithDupValue_IsValid(0));
+  EXPECT_FALSE(unittest::TestEnumWithDupValue_IsValid(4));
+}
+
+TEST(GeneratedEnumTest, MinAndMax) {
+  EXPECT_EQ(unittest::TestAllTypes::FOO,unittest::TestAllTypes::NestedEnum_MIN);
+  EXPECT_EQ(unittest::TestAllTypes::BAZ,unittest::TestAllTypes::NestedEnum_MAX);
+
+  EXPECT_EQ(unittest::FOREIGN_FOO, unittest::ForeignEnum_MIN);
+  EXPECT_EQ(unittest::FOREIGN_BAZ, unittest::ForeignEnum_MAX);
+
+  EXPECT_EQ(1, unittest::TestEnumWithDupValue_MIN);
+  EXPECT_EQ(3, unittest::TestEnumWithDupValue_MAX);
+
+  EXPECT_EQ(unittest::SPARSE_E, unittest::TestSparseEnum_MIN);
+  EXPECT_EQ(unittest::SPARSE_C, unittest::TestSparseEnum_MAX);
+
+  // Make sure we can use _MIN and _MAX as switch cases.
+  switch(unittest::SPARSE_A) {
+    case unittest::TestSparseEnum_MIN:
+    case unittest::TestSparseEnum_MAX:
+      break;
+    default:
+      break;
+  }
+}
+
+// ===================================================================
+
+// Support code for testing services.
+class GeneratedServiceTest : public testing::Test {
+ protected:
+  class MockTestService : public unittest::TestService {
+   public:
+    MockTestService()
+      : called_(false),
+        method_(""),
+        controller_(NULL),
+        request_(NULL),
+        response_(NULL),
+        done_(NULL) {}
+
+    ~MockTestService() {}
+
+    void Reset() { called_ = false; }
+
+    // implements TestService ----------------------------------------
+
+    void Foo(RpcController* controller,
+             const unittest::FooRequest* request,
+             unittest::FooResponse* response,
+             Closure* done) {
+      ASSERT_FALSE(called_);
+      called_ = true;
+      method_ = "Foo";
+      controller_ = controller;
+      request_ = request;
+      response_ = response;
+      done_ = done;
+    }
+
+    void Bar(RpcController* controller,
+             const unittest::BarRequest* request,
+             unittest::BarResponse* response,
+             Closure* done) {
+      ASSERT_FALSE(called_);
+      called_ = true;
+      method_ = "Bar";
+      controller_ = controller;
+      request_ = request;
+      response_ = response;
+      done_ = done;
+    }
+
+    // ---------------------------------------------------------------
+
+    bool called_;
+    string method_;
+    RpcController* controller_;
+    const Message* request_;
+    Message* response_;
+    Closure* done_;
+  };
+
+  class MockRpcChannel : public RpcChannel {
+   public:
+    MockRpcChannel()
+      : called_(false),
+        method_(NULL),
+        controller_(NULL),
+        request_(NULL),
+        response_(NULL),
+        done_(NULL),
+        destroyed_(NULL) {}
+
+    ~MockRpcChannel() {
+      if (destroyed_ != NULL) *destroyed_ = true;
+    }
+
+    void Reset() { called_ = false; }
+
+    // implements TestService ----------------------------------------
+
+    void CallMethod(const MethodDescriptor* method,
+                    RpcController* controller,
+                    const Message* request,
+                    Message* response,
+                    Closure* done) {
+      ASSERT_FALSE(called_);
+      called_ = true;
+      method_ = method;
+      controller_ = controller;
+      request_ = request;
+      response_ = response;
+      done_ = done;
+    }
+
+    // ---------------------------------------------------------------
+
+    bool called_;
+    const MethodDescriptor* method_;
+    RpcController* controller_;
+    const Message* request_;
+    Message* response_;
+    Closure* done_;
+    bool* destroyed_;
+  };
+
+  class MockController : public RpcController {
+   public:
+    void Reset() {
+      ADD_FAILURE() << "Reset() not expected during this test.";
+    }
+    bool Failed() const {
+      ADD_FAILURE() << "Failed() not expected during this test.";
+      return false;
+    }
+    string ErrorText() const {
+      ADD_FAILURE() << "ErrorText() not expected during this test.";
+      return "";
+    }
+    void StartCancel() {
+      ADD_FAILURE() << "StartCancel() not expected during this test.";
+    }
+    void SetFailed(const string& reason) {
+      ADD_FAILURE() << "SetFailed() not expected during this test.";
+    }
+    bool IsCanceled() const {
+      ADD_FAILURE() << "IsCanceled() not expected during this test.";
+      return false;
+    }
+    void NotifyOnCancel(Closure* callback) {
+      ADD_FAILURE() << "NotifyOnCancel() not expected during this test.";
+    }
+  };
+
+  GeneratedServiceTest()
+    : descriptor_(unittest::TestService::descriptor()),
+      foo_(descriptor_->FindMethodByName("Foo")),
+      bar_(descriptor_->FindMethodByName("Bar")),
+      stub_(&mock_channel_),
+      done_(NewPermanentCallback(&DoNothing)) {}
+
+  virtual void SetUp() {
+    ASSERT_TRUE(foo_ != NULL);
+    ASSERT_TRUE(bar_ != NULL);
+  }
+
+  const ServiceDescriptor* descriptor_;
+  const MethodDescriptor* foo_;
+  const MethodDescriptor* bar_;
+
+  MockTestService mock_service_;
+  MockController mock_controller_;
+
+  MockRpcChannel mock_channel_;
+  unittest::TestService::Stub stub_;
+
+  // Just so we don't have to re-define these with every test.
+  unittest::FooRequest foo_request_;
+  unittest::FooResponse foo_response_;
+  unittest::BarRequest bar_request_;
+  unittest::BarResponse bar_response_;
+  scoped_ptr<Closure> done_;
+};
+
+TEST_F(GeneratedServiceTest, GetDescriptor) {
+  // Test that GetDescriptor() works.
+
+  EXPECT_EQ(descriptor_, mock_service_.GetDescriptor());
+}
+
+TEST_F(GeneratedServiceTest, GetChannel) {
+  EXPECT_EQ(&mock_channel_, stub_.channel());
+}
+
+TEST_F(GeneratedServiceTest, OwnsChannel) {
+  MockRpcChannel* channel = new MockRpcChannel;
+  bool destroyed = false;
+  channel->destroyed_ = &destroyed;
+
+  {
+    unittest::TestService::Stub owning_stub(channel,
+                                            Service::STUB_OWNS_CHANNEL);
+    EXPECT_FALSE(destroyed);
+  }
+
+  EXPECT_TRUE(destroyed);
+}
+
+TEST_F(GeneratedServiceTest, CallMethod) {
+  // Test that CallMethod() works.
+
+  // Call Foo() via CallMethod().
+  mock_service_.CallMethod(foo_, &mock_controller_,
+                           &foo_request_, &foo_response_, done_.get());
+
+  ASSERT_TRUE(mock_service_.called_);
+
+  EXPECT_EQ("Foo"            , mock_service_.method_    );
+  EXPECT_EQ(&mock_controller_, mock_service_.controller_);
+  EXPECT_EQ(&foo_request_    , mock_service_.request_   );
+  EXPECT_EQ(&foo_response_   , mock_service_.response_  );
+  EXPECT_EQ(done_.get()      , mock_service_.done_      );
+
+  // Try again, but call Bar() instead.
+  mock_service_.Reset();
+  mock_service_.CallMethod(bar_, &mock_controller_,
+                           &bar_request_, &bar_response_, done_.get());
+
+  ASSERT_TRUE(mock_service_.called_);
+  EXPECT_EQ("Bar", mock_service_.method_);
+}
+
+TEST_F(GeneratedServiceTest, CallMethodTypeFailure) {
+  // Verify death if we call Foo() with Bar's message types.
+
+#ifdef GTEST_HAS_DEATH_TEST  // death tests do not work on Windows yet
+  EXPECT_DEBUG_DEATH(
+    mock_service_.CallMethod(foo_, &mock_controller_,
+                             &foo_request_, &bar_response_, done_.get()),
+    "dynamic_cast");
+
+  mock_service_.Reset();
+  EXPECT_DEBUG_DEATH(
+    mock_service_.CallMethod(foo_, &mock_controller_,
+                             &bar_request_, &foo_response_, done_.get()),
+    "dynamic_cast");
+#endif  // GTEST_HAS_DEATH_TEST
+}
+
+TEST_F(GeneratedServiceTest, GetPrototypes) {
+  // Test Get{Request,Response}Prototype() methods.
+
+  EXPECT_EQ(&unittest::FooRequest::default_instance(),
+            &mock_service_.GetRequestPrototype(foo_));
+  EXPECT_EQ(&unittest::BarRequest::default_instance(),
+            &mock_service_.GetRequestPrototype(bar_));
+
+  EXPECT_EQ(&unittest::FooResponse::default_instance(),
+            &mock_service_.GetResponsePrototype(foo_));
+  EXPECT_EQ(&unittest::BarResponse::default_instance(),
+            &mock_service_.GetResponsePrototype(bar_));
+}
+
+TEST_F(GeneratedServiceTest, Stub) {
+  // Test that the stub class works.
+
+  // Call Foo() via the stub.
+  stub_.Foo(&mock_controller_, &foo_request_, &foo_response_, done_.get());
+
+  ASSERT_TRUE(mock_channel_.called_);
+
+  EXPECT_EQ(foo_             , mock_channel_.method_    );
+  EXPECT_EQ(&mock_controller_, mock_channel_.controller_);
+  EXPECT_EQ(&foo_request_    , mock_channel_.request_   );
+  EXPECT_EQ(&foo_response_   , mock_channel_.response_  );
+  EXPECT_EQ(done_.get()      , mock_channel_.done_      );
+
+  // Call Bar() via the stub.
+  mock_channel_.Reset();
+  stub_.Bar(&mock_controller_, &bar_request_, &bar_response_, done_.get());
+
+  ASSERT_TRUE(mock_channel_.called_);
+  EXPECT_EQ(bar_, mock_channel_.method_);
+}
+
+TEST_F(GeneratedServiceTest, NotImplemented) {
+  // Test that failing to implement a method of a service causes it to fail
+  // with a "not implemented" error message.
+
+  // A service which doesn't implement any methods.
+  class UnimplementedService : public unittest::TestService {
+   public:
+    UnimplementedService() {}
+  };
+
+  UnimplementedService unimplemented_service;
+
+  // And a controller which expects to get a "not implemented" error.
+  class ExpectUnimplementedController : public MockController {
+   public:
+    ExpectUnimplementedController() : called_(false) {}
+
+    void SetFailed(const string& reason) {
+      EXPECT_FALSE(called_);
+      called_ = true;
+      EXPECT_EQ("Method Foo() not implemented.", reason);
+    }
+
+    bool called_;
+  };
+
+  ExpectUnimplementedController controller;
+
+  // Call Foo.
+  unimplemented_service.Foo(&controller, &foo_request_, &foo_response_,
+                            done_.get());
+
+  EXPECT_TRUE(controller.called_);
+}
+
+}  // namespace
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc
new file mode 100644
index 0000000..6118293
--- /dev/null
+++ b/src/google/protobuf/compiler/importer.cc
@@ -0,0 +1,398 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <algorithm>
+
+#include <google/protobuf/compiler/importer.h>
+
+#include <google/protobuf/compiler/parser.h>
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#ifdef _WIN32
+#ifndef F_OK
+#define F_OK 00  // not defined by MSVC for whatever reason
+#endif
+#endif
+
+MultiFileErrorCollector::~MultiFileErrorCollector() {}
+
+// This class serves two purposes:
+// - It implements the ErrorCollector interface (used by Tokenizer and Parser)
+//   in terms of MultiFileErrorCollector, using a particular filename.
+// - It lets us check if any errors have occurred.
+class SourceTreeDescriptorDatabase::SingleFileErrorCollector
+    : public io::ErrorCollector {
+ public:
+  SingleFileErrorCollector(const string& filename,
+                           MultiFileErrorCollector* multi_file_error_collector)
+    : filename_(filename),
+      multi_file_error_collector_(multi_file_error_collector),
+      had_errors_(false) {}
+  ~SingleFileErrorCollector() {}
+
+  bool had_errors() { return had_errors_; }
+
+  // implements ErrorCollector ---------------------------------------
+  void AddError(int line, int column, const string& message) {
+    if (multi_file_error_collector_ != NULL) {
+      multi_file_error_collector_->AddError(filename_, line, column, message);
+    }
+    had_errors_ = true;
+  }
+
+ private:
+  string filename_;
+  MultiFileErrorCollector* multi_file_error_collector_;
+  bool had_errors_;
+};
+
+// ===================================================================
+
+SourceTreeDescriptorDatabase::SourceTreeDescriptorDatabase(
+    SourceTree* source_tree)
+  : source_tree_(source_tree),
+    error_collector_(NULL),
+    using_validation_error_collector_(false),
+    validation_error_collector_(this) {}
+
+SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {}
+
+bool SourceTreeDescriptorDatabase::FindFileByName(
+    const string& filename, FileDescriptorProto* output) {
+  scoped_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename));
+  if (input == NULL) {
+    if (error_collector_ != NULL) {
+      error_collector_->AddError(filename, -1, 0, "File not found.");
+    }
+    return false;
+  }
+
+  // Set up the tokenizer and parser.
+  SingleFileErrorCollector file_error_collector(filename, error_collector_);
+  io::Tokenizer tokenizer(input.get(), &file_error_collector);
+
+  Parser parser;
+  if (error_collector_ != NULL) {
+    parser.RecordErrorsTo(&file_error_collector);
+  }
+  if (using_validation_error_collector_) {
+    parser.RecordSourceLocationsTo(&source_locations_);
+  }
+
+  // Parse it.
+  output->set_name(filename);
+  return parser.Parse(&tokenizer, output) &&
+         !file_error_collector.had_errors();
+}
+
+bool SourceTreeDescriptorDatabase::FindFileContainingSymbol(
+    const string& symbol_name, FileDescriptorProto* output) {
+  return false;
+}
+
+bool SourceTreeDescriptorDatabase::FindFileContainingExtension(
+    const string& containing_type, int field_number,
+    FileDescriptorProto* output) {
+  return false;
+}
+
+// -------------------------------------------------------------------
+
+SourceTreeDescriptorDatabase::ValidationErrorCollector::
+ValidationErrorCollector(SourceTreeDescriptorDatabase* owner)
+  : owner_(owner) {}
+
+SourceTreeDescriptorDatabase::ValidationErrorCollector::
+~ValidationErrorCollector() {}
+
+void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddError(
+    const string& filename,
+    const string& element_name,
+    const Message* descriptor,
+    ErrorLocation location,
+    const string& message) {
+  if (owner_->error_collector_ == NULL) return;
+
+  int line, column;
+  owner_->source_locations_.Find(descriptor, location, &line, &column);
+  owner_->error_collector_->AddError(filename, line, column, message);
+}
+
+// ===================================================================
+
+Importer::Importer(SourceTree* source_tree,
+                   MultiFileErrorCollector* error_collector)
+  : database_(source_tree),
+    pool_(&database_, database_.GetValidationErrorCollector()) {
+  database_.RecordErrorsTo(error_collector);
+}
+
+Importer::~Importer() {}
+
+const FileDescriptor* Importer::Import(const string& filename) {
+  return pool_.FindFileByName(filename);
+}
+
+// ===================================================================
+
+SourceTree::~SourceTree() {}
+
+DiskSourceTree::DiskSourceTree() {}
+
+DiskSourceTree::~DiskSourceTree() {}
+
+static inline char LastChar(const string& str) {
+  return str[str.size() - 1];
+}
+
+// Given a path, returns an equivalent path with these changes:
+// - On Windows, any backslashes are replaced with forward slashes.
+// - Any instances of the directory "." are removed.
+// - Any consecutive '/'s are collapsed into a single slash.
+// Note that the resulting string may be empty.
+//
+// TODO(kenton):  It would be nice to handle "..", e.g. so that we can figure
+//   out that "foo/bar.proto" is inside "baz/../foo".  However, if baz is a
+//   symlink or doesn't exist, then things get complicated, and we can't
+//   actually determine this without investigating the filesystem, probably
+//   in non-portable ways.  So, we punt.
+//
+// TODO(kenton):  It would be nice to use realpath() here except that it
+//   resolves symbolic links.  This could cause problems if people place
+//   symbolic links in their source tree.  For example, if you executed:
+//     protoc --proto_path=foo foo/bar/baz.proto
+//   then if foo/bar is a symbolic link, foo/bar/baz.proto will canonicalize
+//   to a path which does not appear to be under foo, and thus the compiler
+//   will complain that baz.proto is not inside the --proto_path.
+static string CanonicalizePath(string path) {
+#ifdef _WIN32
+  // The Win32 API accepts forward slashes as a path delimiter even though
+  // backslashes are standard.  Let's avoid confusion and use only forward
+  // slashes.
+  path = StringReplace(path, "\\", "/", true);
+#endif
+
+  vector<string> parts;
+  vector<string> canonical_parts;
+  SplitStringUsing(path, "/", &parts);  // Note:  Removes empty parts.
+  for (int i = 0; i < parts.size(); i++) {
+    if (parts[i] == ".") {
+      // Ignore.
+    } else {
+      canonical_parts.push_back(parts[i]);
+    }
+  }
+  string result = JoinStrings(canonical_parts, "/");
+  if (!path.empty() && path[0] == '/') {
+    // Restore leading slash.
+    result = '/' + result;
+  }
+  if (!path.empty() && LastChar(path) == '/' &&
+      !result.empty() && LastChar(result) != '/') {
+    // Restore trailing slash.
+    result += '/';
+  }
+  return result;
+}
+
+static inline bool ContainsParentReference(const string& path) {
+  return path == ".." ||
+         HasPrefixString(path, "../") ||
+         HasSuffixString(path, "/..") ||
+         path.find("/../") != string::npos;
+}
+
+// Maps a file from an old location to a new one.  Typically, old_prefix is
+// a virtual path and new_prefix is its corresponding disk path.  Returns
+// false if the filename did not start with old_prefix, otherwise replaces
+// old_prefix with new_prefix and stores the result in *result.  Examples:
+//   string result;
+//   assert(ApplyMapping("foo/bar", "", "baz", &result));
+//   assert(result == "baz/foo/bar");
+//
+//   assert(ApplyMapping("foo/bar", "foo", "baz", &result));
+//   assert(result == "baz/bar");
+//
+//   assert(ApplyMapping("foo", "foo", "bar", &result));
+//   assert(result == "bar");
+//
+//   assert(!ApplyMapping("foo/bar", "baz", "qux", &result));
+//   assert(!ApplyMapping("foo/bar", "baz", "qux", &result));
+//   assert(!ApplyMapping("foobar", "foo", "baz", &result));
+static bool ApplyMapping(const string& filename,
+                         const string& old_prefix,
+                         const string& new_prefix,
+                         string* result) {
+  if (old_prefix.empty()) {
+    // old_prefix matches any relative path.
+    if (ContainsParentReference(filename)) {
+      // We do not allow the file name to use "..".
+      return false;
+    }
+    if (HasPrefixString(filename, "/")) {
+      // This is an absolute path, so it isn't matched by the empty string.
+      return false;
+    }
+    result->assign(new_prefix);
+    if (!result->empty()) result->push_back('/');
+    result->append(filename);
+    return true;
+  } else if (HasPrefixString(filename, old_prefix)) {
+    // old_prefix is a prefix of the filename.  Is it the whole filename?
+    if (filename.size() == old_prefix.size()) {
+      // Yep, it's an exact match.
+      *result = new_prefix;
+      return true;
+    } else {
+      // Not an exact match.  Is the next character a '/'?  Otherwise,
+      // this isn't actually a match at all.  E.g. the prefix "foo/bar"
+      // does not match the filename "foo/barbaz".
+      if (filename[old_prefix.size()] == '/') {
+        // Yep.  So the prefixes are directories and the filename is a file
+        // inside them.
+        string after_prefix = filename.substr(old_prefix.size() + 1);
+        if (ContainsParentReference(after_prefix)) {
+          // We do not allow the file name to use "..".
+          return false;
+        }
+        result->assign(new_prefix);
+        if (!result->empty()) result->push_back('/');
+        result->append(after_prefix);
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+void DiskSourceTree::MapPath(const string& virtual_path,
+                             const string& disk_path) {
+  mappings_.push_back(Mapping(virtual_path, CanonicalizePath(disk_path)));
+}
+
+DiskSourceTree::DiskFileToVirtualFileResult
+DiskSourceTree::DiskFileToVirtualFile(
+    const string& disk_file,
+    string* virtual_file,
+    string* shadowing_disk_file) {
+  int mapping_index = -1;
+  string canonical_disk_file = CanonicalizePath(disk_file);
+
+  for (int i = 0; i < mappings_.size(); i++) {
+    // Apply the mapping in reverse.
+    if (ApplyMapping(canonical_disk_file, mappings_[i].disk_path,
+                     mappings_[i].virtual_path, virtual_file)) {
+      // Success.
+      mapping_index = i;
+      break;
+    }
+  }
+
+  if (mapping_index == -1) {
+    return NO_MAPPING;
+  }
+
+  // Iterate through all mappings with higher precedence and verify that none
+  // of them map this file to some other existing file.
+  for (int i = 0; i < mapping_index; i++) {
+    if (ApplyMapping(*virtual_file, mappings_[i].virtual_path,
+                     mappings_[i].disk_path, shadowing_disk_file)) {
+      if (access(shadowing_disk_file->c_str(), F_OK) >= 0) {
+        // File exists.
+        return SHADOWED;
+      }
+    }
+  }
+  shadowing_disk_file->clear();
+
+  // Verify that we can open the file.  Note that this also has the side-effect
+  // of verifying that we are not canonicalizing away any non-existent
+  // directories.
+  scoped_ptr<io::ZeroCopyInputStream> stream(OpenDiskFile(disk_file));
+  if (stream == NULL) {
+    return CANNOT_OPEN;
+  }
+
+  return SUCCESS;
+}
+
+io::ZeroCopyInputStream* DiskSourceTree::Open(const string& filename) {
+  if (filename != CanonicalizePath(filename) ||
+      ContainsParentReference(filename)) {
+    // We do not allow importing of paths containing things like ".." or
+    // consecutive slashes since the compiler expects files to be uniquely
+    // identified by file name.
+    return NULL;
+  }
+
+  for (int i = 0; i < mappings_.size(); i++) {
+    string disk_file;
+    if (ApplyMapping(filename, mappings_[i].virtual_path,
+                     mappings_[i].disk_path, &disk_file)) {
+      io::ZeroCopyInputStream* stream = OpenDiskFile(disk_file);
+      if (stream != NULL) return stream;
+
+      if (errno == EACCES) {
+        // The file exists but is not readable.
+        // TODO(kenton):  Find a way to report this more nicely.
+        GOOGLE_LOG(WARNING) << "Read access is denied for file: " << disk_file;
+        return NULL;
+      }
+    }
+  }
+
+  return NULL;
+}
+
+io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile(
+    const string& filename) {
+  int file_descriptor;
+  do {
+    file_descriptor = open(filename.c_str(), O_RDONLY);
+  } while (file_descriptor < 0 && errno == EINTR);
+  if (file_descriptor >= 0) {
+    io::FileInputStream* result = new io::FileInputStream(file_descriptor);
+    result->SetCloseOnDelete(true);
+    return result;
+  } else {
+    return NULL;
+  }
+}
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h
new file mode 100644
index 0000000..2e3d0df
--- /dev/null
+++ b/src/google/protobuf/compiler/importer.h
@@ -0,0 +1,279 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file is the public interface to the .proto file parser.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
+#define GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
+
+#include <string>
+#include <vector>
+#include <set>
+#include <utility>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/compiler/parser.h>
+
+namespace google {
+namespace protobuf {
+
+namespace io { class ZeroCopyInputStream; }
+
+namespace compiler {
+
+// Defined in this file.
+class Importer;
+class MultiFileErrorCollector;
+class SourceTree;
+class DiskSourceTree;
+
+// TODO(kenton):  Move all SourceTree stuff to a separate file?
+
+// An implementation of DescriptorDatabase which loads files from a SourceTree
+// and parses them.
+//
+// Note:  This class is not thread-safe since it maintains a table of source
+//   code locations for error reporting.  However, when a DescriptorPool wraps
+//   a DescriptorDatabase, it uses mutex locking to make sure only one method
+//   of the database is called at a time, even if the DescriptorPool is used
+//   from multiple threads.  Therefore, there is only a problem if you create
+//   multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase
+//   and use them from multiple threads.
+//
+// Note:  This class does not implement FindFileContainingSymbol() or
+//   FindFileContainingExtension(); these will always return false.
+class LIBPROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase {
+ public:
+  SourceTreeDescriptorDatabase(SourceTree* source_tree);
+  ~SourceTreeDescriptorDatabase();
+
+  // Instructs the SourceTreeDescriptorDatabase to report any parse errors
+  // to the given MultiFileErrorCollector.  This should be called before
+  // parsing.  error_collector must remain valid until either this method
+  // is called again or the SourceTreeDescriptorDatabase is destroyed.
+  void RecordErrorsTo(MultiFileErrorCollector* error_collector) {
+    error_collector_ = error_collector;
+  }
+
+  // Gets a DescriptorPool::ErrorCollector which records errors to the
+  // MultiFileErrorCollector specified with RecordErrorsTo().  This collector
+  // has the ability to determine exact line and column numbers of errors
+  // from the information given to it by the DescriptorPool.
+  DescriptorPool::ErrorCollector* GetValidationErrorCollector() {
+    using_validation_error_collector_ = true;
+    return &validation_error_collector_;
+  }
+
+  // implements DescriptorDatabase -----------------------------------
+  bool FindFileByName(const string& filename, FileDescriptorProto* output);
+  bool FindFileContainingSymbol(const string& symbol_name,
+                                FileDescriptorProto* output);
+  bool FindFileContainingExtension(const string& containing_type,
+                                   int field_number,
+                                   FileDescriptorProto* output);
+
+ private:
+  class SingleFileErrorCollector;
+
+  SourceTree* source_tree_;
+  MultiFileErrorCollector* error_collector_;
+
+  class LIBPROTOBUF_EXPORT ValidationErrorCollector : public DescriptorPool::ErrorCollector {
+   public:
+    ValidationErrorCollector(SourceTreeDescriptorDatabase* owner);
+    ~ValidationErrorCollector();
+
+    // implements ErrorCollector ---------------------------------------
+    void AddError(const string& filename,
+                  const string& element_name,
+                  const Message* descriptor,
+                  ErrorLocation location,
+                  const string& message);
+
+   private:
+    SourceTreeDescriptorDatabase* owner_;
+  };
+  friend class ValidationErrorCollector;
+
+  bool using_validation_error_collector_;
+  SourceLocationTable source_locations_;
+  ValidationErrorCollector validation_error_collector_;
+};
+
+// Simple interface for parsing .proto files.  This wraps the process
+// of opening the file, parsing it with a Parser, recursively parsing all its
+// imports, and then cross-linking the results to produce a FileDescriptor.
+//
+// This is really just a thin wrapper around SourceTreeDescriptorDatabase.
+// You may find that SourceTreeDescriptorDatabase is more flexible.
+//
+// TODO(kenton):  I feel like this class is not well-named.
+class LIBPROTOBUF_EXPORT Importer {
+ public:
+  Importer(SourceTree* source_tree,
+           MultiFileErrorCollector* error_collector);
+  ~Importer();
+
+  // Import the given file and build a FileDescriptor representing it.  If
+  // the file is already in the DescriptorPool, the existing FileDescriptor
+  // will be returned.  The FileDescriptor is property of the DescriptorPool,
+  // and will remain valid until it is destroyed.  If any errors occur, they
+  // will be reported using the error collector and Import() will return NULL.
+  //
+  // A particular Importer object will only report errors for a particular
+  // file once.  All future attempts to import the same file will return NULL
+  // without reporting any errors.  The idea is that you might want to import
+  // a lot of files without seeing the same errors over and over again.  If
+  // you want to see errors for the same files repeatedly, you can use a
+  // separate Importer object to import each one (but use the same
+  // DescriptorPool so that they can be cross-linked).
+  const FileDescriptor* Import(const string& filename);
+
+  // The DescriptorPool in which all imported FileDescriptors and their
+  // contents are stored.
+  inline const DescriptorPool* pool() const {
+    return &pool_;
+  }
+
+ private:
+  SourceTreeDescriptorDatabase database_;
+  DescriptorPool pool_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Importer);
+};
+
+// If the importer encounters problems while trying to import the proto files,
+// it reports them to a MultiFileErrorCollector.
+class LIBPROTOBUF_EXPORT MultiFileErrorCollector {
+ public:
+  inline MultiFileErrorCollector() {}
+  virtual ~MultiFileErrorCollector();
+
+  // Line and column numbers are zero-based.  A line number of -1 indicates
+  // an error with the entire file (e.g. "not found").
+  virtual void AddError(const string& filename, int line, int column,
+                        const string& message) = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector);
+};
+
+// Abstract interface which represents a directory tree containing proto files.
+// Used by the default implementation of Importer to resolve import statements
+// Most users will probably want to use the DiskSourceTree implementation,
+// below.
+class LIBPROTOBUF_EXPORT SourceTree {
+ public:
+  inline SourceTree() {}
+  virtual ~SourceTree();
+
+  // Open the given file and return a stream that reads it, or NULL if not
+  // found.  The caller takes ownership of the returned object.  The filename
+  // must be a path relative to the root of the source tree and must not
+  // contain "." or ".." components.
+  virtual io::ZeroCopyInputStream* Open(const string& filename) = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceTree);
+};
+
+// An implementation of SourceTree which loads files from locations on disk.
+// Multiple mappings can be set up to map locations in the DiskSourceTree to
+// locations in the physical filesystem.
+class LIBPROTOBUF_EXPORT DiskSourceTree : public SourceTree {
+ public:
+  DiskSourceTree();
+  ~DiskSourceTree();
+
+  // Map a path on disk to a location in the SourceTree.  The path may be
+  // either a file or a directory.  If it is a directory, the entire tree
+  // under it will be mapped to the given virtual location.  To map a directory
+  // to the root of the source tree, pass an empty string for virtual_path.
+  //
+  // If multiple mapped paths apply when opening a file, they will be searched
+  // in order.  For example, if you do:
+  //   MapPath("bar", "foo/bar");
+  //   MapPath("", "baz");
+  // and then you do:
+  //   Open("bar/qux");
+  // the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux,
+  // returning the first one that opens successfuly.
+  //
+  // disk_path may be an absolute path or relative to the current directory,
+  // just like a path you'd pass to open().
+  void MapPath(const string& virtual_path, const string& disk_path);
+
+  // Return type for DiskFileToVirtualFile().
+  enum DiskFileToVirtualFileResult {
+    SUCCESS,
+    SHADOWED,
+    CANNOT_OPEN,
+    NO_MAPPING
+  };
+
+  // Given a path to a file on disk, find a virtual path mapping to that
+  // file.  The first mapping created with MapPath() whose disk_path contains
+  // the filename is used.  However, that virtual path may not actually be
+  // usable to open the given file.  Possible return values are:
+  // * SUCCESS: The mapping was found.  *virtual_file is filled in so that
+  //   calling Open(*virtual_file) will open the file named by disk_file.
+  // * SHADOWED: A mapping was found, but using Open() to open this virtual
+  //   path will end up returning some different file.  This is because some
+  //   other mapping with a higher precedence also matches this virtual path
+  //   and maps it to a different file that exists on disk.  *virtual_file
+  //   is filled in as it would be in the SUCCESS case.  *shadowing_disk_file
+  //   is filled in with the disk path of the file which would be opened if
+  //   you were to call Open(*virtual_file).
+  // * CANNOT_OPEN: The mapping was found and was not shadowed, but the
+  //   file specified cannot be opened.  When this value is returned,
+  //   errno will indicate the reason the file cannot be opened.  *virtual_file
+  //   will be set to the virtual path as in the SUCCESS case, even though
+  //   it is not useful.
+  // * NO_MAPPING: Indicates that no mapping was found which contains this
+  //   file.
+  DiskFileToVirtualFileResult
+    DiskFileToVirtualFile(const string& disk_file,
+                          string* virtual_file,
+                          string* shadowing_disk_file);
+
+  // implements SourceTree -------------------------------------------
+  io::ZeroCopyInputStream* Open(const string& filename);
+
+ private:
+  struct Mapping {
+    string virtual_path;
+    string disk_path;
+
+    inline Mapping(const string& virtual_path, const string& disk_path)
+      : virtual_path(virtual_path), disk_path(disk_path) {}
+  };
+  vector<Mapping> mappings_;
+
+  // Like Open() but given the actual on-disk path.
+  io::ZeroCopyInputStream* OpenDiskFile(const string& filename);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DiskSourceTree);
+};
+
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc
new file mode 100644
index 0000000..5b5d283
--- /dev/null
+++ b/src/google/protobuf/compiler/importer_unittest.cc
@@ -0,0 +1,539 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+
+#define EXPECT_SUBSTRING(needle, haystack) \
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, (needle), (haystack))
+
+class MockErrorCollector : public MultiFileErrorCollector {
+ public:
+  MockErrorCollector() {}
+  ~MockErrorCollector() {}
+
+  string text_;
+
+  // implements ErrorCollector ---------------------------------------
+  void AddError(const string& filename, int line, int column,
+                const string& message) {
+    strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n",
+                                 filename, line, column, message);
+  }
+};
+
+// -------------------------------------------------------------------
+
+// A dummy implementation of SourceTree backed by a simple map.
+class MockSourceTree : public SourceTree {
+ public:
+  MockSourceTree() {}
+  ~MockSourceTree() {}
+
+  void AddFile(const string& name, const char* contents) {
+    files_[name] = contents;
+  }
+
+  // implements SourceTree -------------------------------------------
+  io::ZeroCopyInputStream* Open(const string& filename) {
+    const char* contents = FindPtrOrNull(files_, filename);
+    if (contents == NULL) {
+      return NULL;
+    } else {
+      return new io::ArrayInputStream(contents, strlen(contents));
+    }
+  }
+
+ private:
+  hash_map<string, const char*> files_;
+};
+
+// ===================================================================
+
+class ImporterTest : public testing::Test {
+ protected:
+  ImporterTest()
+    : importer_(&source_tree_, &error_collector_) {}
+
+  void AddFile(const string& filename, const char* text) {
+    source_tree_.AddFile(filename, text);
+  }
+
+  // Return the collected error text
+  string error() const { return error_collector_.text_; }
+
+  MockErrorCollector error_collector_;
+  MockSourceTree source_tree_;
+  Importer importer_;
+};
+
+TEST_F(ImporterTest, Import) {
+  // Test normal importing.
+  AddFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  const FileDescriptor* file = importer_.Import("foo.proto");
+  EXPECT_EQ("", error_collector_.text_);
+  ASSERT_TRUE(file != NULL);
+
+  ASSERT_EQ(1, file->message_type_count());
+  EXPECT_EQ("Foo", file->message_type(0)->name());
+
+  // Importing again should return same object.
+  EXPECT_EQ(file, importer_.Import("foo.proto"));
+}
+
+TEST_F(ImporterTest, ImportNested) {
+  // Test that importing a file which imports another file works.
+  AddFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "import \"bar.proto\";\n"
+    "message Foo {\n"
+    "  optional Bar bar = 1;\n"
+    "}\n");
+  AddFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "message Bar {}\n");
+
+  // Note that both files are actually parsed by the first call to Import()
+  // here, since foo.proto imports bar.proto.  The second call just returns
+  // the same ProtoFile for bar.proto which was constructed while importing
+  // foo.proto.  We test that this is the case below by checking that bar
+  // is among foo's dependencies (by pointer).
+  const FileDescriptor* foo = importer_.Import("foo.proto");
+  const FileDescriptor* bar = importer_.Import("bar.proto");
+  EXPECT_EQ("", error_collector_.text_);
+  ASSERT_TRUE(foo != NULL);
+  ASSERT_TRUE(bar != NULL);
+
+  // Check that foo's dependency is the same object as bar.
+  ASSERT_EQ(1, foo->dependency_count());
+  EXPECT_EQ(bar, foo->dependency(0));
+
+  // Check that foo properly cross-links bar.
+  ASSERT_EQ(1, foo->message_type_count());
+  ASSERT_EQ(1, bar->message_type_count());
+  ASSERT_EQ(1, foo->message_type(0)->field_count());
+  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE,
+            foo->message_type(0)->field(0)->type());
+  EXPECT_EQ(bar->message_type(0),
+            foo->message_type(0)->field(0)->message_type());
+}
+
+TEST_F(ImporterTest, FileNotFound) {
+  // Error:  Parsing a file that doesn't exist.
+  EXPECT_TRUE(importer_.Import("foo.proto") == NULL);
+  EXPECT_EQ(
+    "foo.proto:-1:0: File not found.\n",
+    error_collector_.text_);
+}
+
+TEST_F(ImporterTest, ImportNotFound) {
+  // Error:  Importing a file that doesn't exist.
+  AddFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "import \"bar.proto\";\n");
+
+  EXPECT_TRUE(importer_.Import("foo.proto") == NULL);
+  EXPECT_EQ(
+    "bar.proto:-1:0: File not found.\n"
+    "foo.proto:-1:0: Import \"bar.proto\" was not found or had errors.\n",
+    error_collector_.text_);
+}
+
+TEST_F(ImporterTest, RecursiveImport) {
+  // Error:  Recursive import.
+  AddFile("recursive1.proto",
+    "syntax = \"proto2\";\n"
+    "import \"recursive2.proto\";\n");
+  AddFile("recursive2.proto",
+    "syntax = \"proto2\";\n"
+    "import \"recursive1.proto\";\n");
+
+  EXPECT_TRUE(importer_.Import("recursive1.proto") == NULL);
+  EXPECT_EQ(
+    "recursive1.proto:-1:0: File recursively imports itself: recursive1.proto "
+      "-> recursive2.proto -> recursive1.proto\n"
+    "recursive2.proto:-1:0: Import \"recursive1.proto\" was not found "
+      "or had errors.\n"
+    "recursive1.proto:-1:0: Import \"recursive2.proto\" was not found "
+      "or had errors.\n",
+    error_collector_.text_);
+}
+
+// TODO(sanjay): The MapField tests below more properly belong in
+// descriptor_unittest, but are more convenient to test here.
+TEST_F(ImporterTest, MapFieldValid) {
+  AddFile(
+      "map.proto",
+      "syntax = \"proto2\";\n"
+      "message Item {\n"
+      "  required string key = 1;\n"
+      "}\n"
+      "message Map {\n"
+      "  repeated Item items = 1 [experimental_map_key = \"key\"];\n"
+      "}\n"
+      );
+  const FileDescriptor* file = importer_.Import("map.proto");
+  ASSERT_TRUE(file != NULL) << error_collector_.text_;
+  EXPECT_EQ("", error_collector_.text_);
+
+  // Check that Map::items points to Item::key
+  const Descriptor* item_type = file->FindMessageTypeByName("Item");
+  ASSERT_TRUE(item_type != NULL);
+  const Descriptor* map_type = file->FindMessageTypeByName("Map");
+  ASSERT_TRUE(map_type != NULL);
+  const FieldDescriptor* key_field = item_type->FindFieldByName("key");
+  ASSERT_TRUE(key_field != NULL);
+  const FieldDescriptor* items_field = map_type->FindFieldByName("items");
+  ASSERT_TRUE(items_field != NULL);
+  EXPECT_EQ(items_field->experimental_map_key(), key_field);
+}
+
+TEST_F(ImporterTest, MapFieldNotRepeated) {
+  AddFile(
+      "map.proto",
+      "syntax = \"proto2\";\n"
+      "message Item {\n"
+      "  required string key = 1;\n"
+      "}\n"
+      "message Map {\n"
+      "  required Item items = 1 [experimental_map_key = \"key\"];\n"
+      "}\n"
+      );
+  EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+  EXPECT_SUBSTRING("only allowed for repeated fields", error());
+}
+
+TEST_F(ImporterTest, MapFieldNotMessageType) {
+  AddFile(
+      "map.proto",
+      "syntax = \"proto2\";\n"
+      "message Map {\n"
+      "  repeated int32 items = 1 [experimental_map_key = \"key\"];\n"
+      "}\n"
+      );
+  EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+  EXPECT_SUBSTRING("only allowed for fields with a message type", error());
+}
+
+TEST_F(ImporterTest, MapFieldTypeNotFound) {
+  AddFile(
+      "map.proto",
+      "syntax = \"proto2\";\n"
+      "message Map {\n"
+      "  repeated Unknown items = 1 [experimental_map_key = \"key\"];\n"
+      "}\n"
+      );
+  EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+  EXPECT_SUBSTRING("not defined", error());
+}
+
+TEST_F(ImporterTest, MapFieldKeyNotFound) {
+  AddFile(
+      "map.proto",
+      "syntax = \"proto2\";\n"
+      "message Item {\n"
+      "  required string key = 1;\n"
+      "}\n"
+      "message Map {\n"
+      "  repeated Item items = 1 [experimental_map_key = \"badkey\"];\n"
+      "}\n"
+      );
+  EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+  EXPECT_SUBSTRING("Could not find field", error());
+}
+
+TEST_F(ImporterTest, MapFieldKeyRepeated) {
+  AddFile(
+      "map.proto",
+      "syntax = \"proto2\";\n"
+      "message Item {\n"
+      "  repeated string key = 1;\n"
+      "}\n"
+      "message Map {\n"
+      "  repeated Item items = 1 [experimental_map_key = \"key\"];\n"
+      "}\n"
+      );
+  EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+  EXPECT_SUBSTRING("must not name a repeated field", error());
+}
+
+TEST_F(ImporterTest, MapFieldKeyNotScalar) {
+  AddFile(
+      "map.proto",
+      "syntax = \"proto2\";\n"
+      "message ItemKey { }\n"
+      "message Item {\n"
+      "  required ItemKey key = 1;\n"
+      "}\n"
+      "message Map {\n"
+      "  repeated Item items = 1 [experimental_map_key = \"key\"];\n"
+      "}\n"
+      );
+  EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+  EXPECT_SUBSTRING("must name a scalar or string", error());
+}
+
+// ===================================================================
+
+class DiskSourceTreeTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_1");
+    dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_2");
+
+    for (int i = 0; i < dirnames_.size(); i++) {
+      if (File::Exists(dirnames_[i])) {
+        File::DeleteRecursively(dirnames_[i], NULL, NULL);
+      }
+      GOOGLE_CHECK(File::CreateDir(dirnames_[i].c_str(), DEFAULT_FILE_MODE));
+    }
+  }
+
+  virtual void TearDown() {
+    for (int i = 0; i < dirnames_.size(); i++) {
+      File::DeleteRecursively(dirnames_[i], NULL, NULL);
+    }
+  }
+
+  void AddFile(const string& filename, const char* contents) {
+    File::WriteStringToFileOrDie(contents, filename);
+  }
+
+  void AddSubdir(const string& dirname) {
+    GOOGLE_CHECK(File::CreateDir(dirname.c_str(), DEFAULT_FILE_MODE));
+  }
+
+  void ExpectFileContents(const string& filename,
+                          const char* expected_contents) {
+    scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
+
+    ASSERT_FALSE(input == NULL);
+
+    // Read all the data from the file.
+    string file_contents;
+    const void* data;
+    int size;
+    while (input->Next(&data, &size)) {
+      file_contents.append(reinterpret_cast<const char*>(data), size);
+    }
+
+    EXPECT_EQ(expected_contents, file_contents);
+  }
+
+  void ExpectFileNotFound(const string& filename) {
+    scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
+    EXPECT_TRUE(input == NULL);
+  }
+
+  DiskSourceTree source_tree_;
+
+  // Paths of two on-disk directories to use during the test.
+  vector<string> dirnames_;
+};
+
+TEST_F(DiskSourceTreeTest, MapRoot) {
+  // Test opening a file in a directory that is mapped to the root of the
+  // source tree.
+  AddFile(dirnames_[0] + "/foo", "Hello World!");
+  source_tree_.MapPath("", dirnames_[0]);
+
+  ExpectFileContents("foo", "Hello World!");
+  ExpectFileNotFound("bar");
+}
+
+TEST_F(DiskSourceTreeTest, MapDirectory) {
+  // Test opening a file in a directory that is mapped to somewhere other
+  // than the root of the source tree.
+
+  AddFile(dirnames_[0] + "/foo", "Hello World!");
+  source_tree_.MapPath("baz", dirnames_[0]);
+
+  ExpectFileContents("baz/foo", "Hello World!");
+  ExpectFileNotFound("baz/bar");
+  ExpectFileNotFound("foo");
+  ExpectFileNotFound("bar");
+
+  // Non-canonical file names should not work.
+  ExpectFileNotFound("baz//foo");
+  ExpectFileNotFound("baz/../baz/foo");
+  ExpectFileNotFound("baz/./foo");
+  ExpectFileNotFound("baz/foo/");
+}
+
+TEST_F(DiskSourceTreeTest, NoParent) {
+  // Test that we cannot open files in a parent of a mapped directory.
+
+  AddFile(dirnames_[0] + "/foo", "Hello World!");
+  AddSubdir(dirnames_[0] + "/bar");
+  AddFile(dirnames_[0] + "/bar/baz", "Blah.");
+  source_tree_.MapPath("", dirnames_[0] + "/bar");
+
+  ExpectFileContents("baz", "Blah.");
+  ExpectFileNotFound("../foo");
+  ExpectFileNotFound("../bar/baz");
+}
+
+TEST_F(DiskSourceTreeTest, MapFile) {
+  // Test opening a file that is mapped directly into the source tree.
+
+  AddFile(dirnames_[0] + "/foo", "Hello World!");
+  source_tree_.MapPath("foo", dirnames_[0] + "/foo");
+
+  ExpectFileContents("foo", "Hello World!");
+  ExpectFileNotFound("bar");
+}
+
+TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) {
+  // Test mapping and searching multiple directories.
+
+  AddFile(dirnames_[0] + "/foo", "Hello World!");
+  AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+  AddFile(dirnames_[1] + "/bar", "Goodbye World!");
+  source_tree_.MapPath("", dirnames_[0]);
+  source_tree_.MapPath("", dirnames_[1]);
+
+  ExpectFileContents("foo", "Hello World!");
+  ExpectFileContents("bar", "Goodbye World!");
+  ExpectFileNotFound("baz");
+}
+
+TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) {
+  // Test that directories are always searched in order, even when a latter
+  // directory is more-specific than a former one.
+
+  // Create the "bar" directory so we can put a file in it.
+  ASSERT_TRUE(File::CreateDir((dirnames_[0] + "/bar").c_str(),
+                              DEFAULT_FILE_MODE));
+
+  // Add files and map paths.
+  AddFile(dirnames_[0] + "/bar/foo", "Hello World!");
+  AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+  source_tree_.MapPath("", dirnames_[0]);
+  source_tree_.MapPath("bar", dirnames_[1]);
+
+  // Check.
+  ExpectFileContents("bar/foo", "Hello World!");
+}
+
+TEST_F(DiskSourceTreeTest, DiskFileToVirtualFile) {
+  // Test DiskFileToVirtualFile.
+
+  AddFile(dirnames_[0] + "/foo", "Hello World!");
+  AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+  source_tree_.MapPath("bar", dirnames_[0]);
+  source_tree_.MapPath("bar", dirnames_[1]);
+
+  string virtual_file;
+  string shadowing_disk_file;
+
+  EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+    source_tree_.DiskFileToVirtualFile(
+      "/foo", &virtual_file, &shadowing_disk_file));
+
+  EXPECT_EQ(DiskSourceTree::SHADOWED,
+    source_tree_.DiskFileToVirtualFile(
+      dirnames_[1] + "/foo", &virtual_file, &shadowing_disk_file));
+  EXPECT_EQ("bar/foo", virtual_file);
+  EXPECT_EQ(dirnames_[0] + "/foo", shadowing_disk_file);
+
+  EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+    source_tree_.DiskFileToVirtualFile(
+      dirnames_[1] + "/baz", &virtual_file, &shadowing_disk_file));
+  EXPECT_EQ("bar/baz", virtual_file);
+
+  EXPECT_EQ(DiskSourceTree::SUCCESS,
+    source_tree_.DiskFileToVirtualFile(
+      dirnames_[0] + "/foo", &virtual_file, &shadowing_disk_file));
+  EXPECT_EQ("bar/foo", virtual_file);
+}
+
+TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) {
+  // Test handling of "..", ".", etc. in DiskFileToVirtualFile().
+
+  source_tree_.MapPath("dir1", "..");
+  source_tree_.MapPath("dir2", "../../foo");
+  source_tree_.MapPath("dir3", "./foo/bar/.");
+  source_tree_.MapPath("dir4", ".");
+  source_tree_.MapPath("", "/qux");
+
+  string virtual_file;
+  string shadowing_disk_file;
+
+  // "../.." should not be considered to be under "..".
+  EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+    source_tree_.DiskFileToVirtualFile(
+      "../../baz", &virtual_file, &shadowing_disk_file));
+
+  // But "../baz" should be.
+  EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+    source_tree_.DiskFileToVirtualFile(
+      "../baz", &virtual_file, &shadowing_disk_file));
+  EXPECT_EQ("dir1/baz", virtual_file);
+
+  // "../../foo/baz" is under "../../foo".
+  EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+    source_tree_.DiskFileToVirtualFile(
+      "../../foo/baz", &virtual_file, &shadowing_disk_file));
+  EXPECT_EQ("dir2/baz", virtual_file);
+
+  // "foo/./bar/baz" is under "./foo/bar/.".
+  EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+    source_tree_.DiskFileToVirtualFile(
+      "foo/bar/baz", &virtual_file, &shadowing_disk_file));
+  EXPECT_EQ("dir3/baz", virtual_file);
+
+  // "bar" is under ".".
+  EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+    source_tree_.DiskFileToVirtualFile(
+      "bar", &virtual_file, &shadowing_disk_file));
+  EXPECT_EQ("dir4/bar", virtual_file);
+
+  // "/qux/baz" is under "/qux".
+  EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+    source_tree_.DiskFileToVirtualFile(
+      "/qux/baz", &virtual_file, &shadowing_disk_file));
+  EXPECT_EQ("baz", virtual_file);
+}
+
+}  // namespace
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc
new file mode 100644
index 0000000..aa15a46
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_enum.cc
@@ -0,0 +1,189 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  for (int i = 0; i < descriptor_->value_count(); i++) {
+    const EnumValueDescriptor* value = descriptor_->value(i);
+    const EnumValueDescriptor* canonical_value =
+      descriptor_->FindValueByNumber(value->number());
+
+    if (value == canonical_value) {
+      canonical_values_.push_back(value);
+    } else {
+      Alias alias;
+      alias.value = value;
+      alias.canonical_value = canonical_value;
+      aliases_.push_back(alias);
+    }
+  }
+}
+
+EnumGenerator::~EnumGenerator() {}
+
+void EnumGenerator::Generate(io::Printer* printer) {
+  bool is_own_file =
+    descriptor_->containing_type() == NULL &&
+    descriptor_->file()->options().java_multiple_files();
+  printer->Print(
+    "public $static$ enum $classname$ {\n",
+    "static", is_own_file ? "" : "static",
+    "classname", descriptor_->name());
+  printer->Indent();
+
+  for (int i = 0; i < canonical_values_.size(); i++) {
+    map<string, string> vars;
+    vars["name"] = canonical_values_[i]->name();
+    vars["index"] = SimpleItoa(canonical_values_[i]->index());
+    vars["number"] = SimpleItoa(canonical_values_[i]->number());
+    printer->Print(vars,
+      "$name$($index$, $number$),\n");
+  }
+
+  printer->Print(
+    ";\n"
+    "\n");
+
+  // -----------------------------------------------------------------
+
+  for (int i = 0; i < aliases_.size(); i++) {
+    map<string, string> vars;
+    vars["classname"] = descriptor_->name();
+    vars["name"] = aliases_[i].value->name();
+    vars["canonical_name"] = aliases_[i].canonical_value->name();
+    printer->Print(vars,
+      "public static final $classname$ $name$ = $canonical_name$;\n");
+  }
+
+  // -----------------------------------------------------------------
+
+  printer->Print(
+    "\n"
+    "public final int getNumber() { return value; }\n"
+    "\n"
+    "public static $classname$ valueOf(int value) {\n"
+    "  switch (value) {\n",
+    "classname", descriptor_->name());
+  printer->Indent();
+  printer->Indent();
+
+  for (int i = 0; i < canonical_values_.size(); i++) {
+    printer->Print(
+      "case $number$: return $name$;\n",
+      "name", canonical_values_[i]->name(),
+      "number", SimpleItoa(canonical_values_[i]->number()));
+  }
+
+  printer->Outdent();
+  printer->Outdent();
+  printer->Print(
+    "    default: return null;\n"
+    "  }\n"
+    "}\n"
+    "\n");
+
+  // -----------------------------------------------------------------
+  // Reflection
+
+  printer->Print(
+    "public final com.google.protobuf.Descriptors.EnumValueDescriptor\n"
+    "    getValueDescriptor() {\n"
+    "  return getDescriptor().getValues().get(index);\n"
+    "}\n"
+    "public final com.google.protobuf.Descriptors.EnumDescriptor\n"
+    "    getDescriptorForType() {\n"
+    "  return getDescriptor();\n"
+    "}\n"
+    "public static final com.google.protobuf.Descriptors.EnumDescriptor\n"
+    "    getDescriptor() {\n");
+
+  // TODO(kenton):  Cache statically?  Note that we can't access descriptors
+  //   at module init time because it wouldn't work with descriptor.proto, but
+  //   we can cache the value the first time getDescriptor() is called.
+  if (descriptor_->containing_type() == NULL) {
+    printer->Print(
+      "  return $file$.getDescriptor().getEnumTypes().get($index$);\n",
+      "file", ClassName(descriptor_->file()),
+      "index", SimpleItoa(descriptor_->index()));
+  } else {
+    printer->Print(
+      "  return $parent$.getDescriptor().getEnumTypes().get($index$);\n",
+      "parent", ClassName(descriptor_->containing_type()),
+      "index", SimpleItoa(descriptor_->index()));
+  }
+
+  printer->Print(
+    "}\n"
+    "\n"
+    "private static final $classname$[] VALUES = {\n"
+    "  ",
+    "classname", descriptor_->name());
+
+  for (int i = 0; i < descriptor_->value_count(); i++) {
+    printer->Print("$name$, ",
+      "name", descriptor_->value(i)->name());
+  }
+
+  printer->Print(
+    "\n"
+    "};\n"
+    "public static $classname$ valueOf(\n"
+    "    com.google.protobuf.Descriptors.EnumValueDescriptor desc) {\n"
+    "  if (desc.getType() != getDescriptor()) {\n"
+    "    throw new java.lang.IllegalArgumentException(\n"
+    "      \"EnumValueDescriptor is not for this type.\");\n"
+    "  }\n"
+    "  return VALUES[desc.getIndex()];\n"
+    "}\n",
+    "classname", descriptor_->name());
+
+  // -----------------------------------------------------------------
+
+  printer->Print(
+    "private final int index;\n"
+    "private final int value;\n"
+    "private $classname$(int index, int value) {\n"
+    "  this.index = index;\n"
+    "  this.value = value;\n"
+    "}\n",
+    "classname", descriptor_->name());
+
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_enum.h b/src/google/protobuf/compiler/java/java_enum.h
new file mode 100644
index 0000000..f0a1603
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_enum.h
@@ -0,0 +1,70 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class EnumGenerator {
+ public:
+  explicit EnumGenerator(const EnumDescriptor* descriptor);
+  ~EnumGenerator();
+
+  void Generate(io::Printer* printer);
+
+ private:
+  const EnumDescriptor* descriptor_;
+
+  // The proto language allows multiple enum constants to have the same numeric
+  // value.  Java, however, does not allow multiple enum constants to be
+  // considered equivalent.  We treat the first defined constant for any
+  // given numeric value as "canonical" and the rest as aliases of that
+  // canonical value.
+  vector<const EnumValueDescriptor*> canonical_values_;
+
+  struct Alias {
+    const EnumValueDescriptor* value;
+    const EnumValueDescriptor* canonical_value;
+  };
+  vector<Alias> aliases_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
new file mode 100644
index 0000000..cb80c4b
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -0,0 +1,264 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_enum_field.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+// TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
+//   repeat code between this and the other field types.
+void SetEnumVariables(const FieldDescriptor* descriptor,
+                      map<string, string>* variables) {
+  const EnumValueDescriptor* default_value;
+  default_value = descriptor->default_value_enum();
+
+  string type = ClassName(descriptor->enum_type());
+
+  (*variables)["name"] =
+    UnderscoresToCamelCase(descriptor);
+  (*variables)["capitalized_name"] =
+    UnderscoresToCapitalizedCamelCase(descriptor);
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["type"] = type;
+  (*variables)["default"] = type + "." + default_value->name();
+}
+
+}  // namespace
+
+// ===================================================================
+
+EnumFieldGenerator::
+EnumFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetEnumVariables(descriptor, &variables_);
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {}
+
+void EnumFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private boolean has$capitalized_name$;\n"
+    "private $type$ $name$_ = $default$;\n"
+    "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
+    "public $type$ get$capitalized_name$() { return $name$_; }\n");
+}
+
+void EnumFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "public boolean has$capitalized_name$() {\n"
+    "  return result.has$capitalized_name$();\n"
+    "}\n"
+    "public $type$ get$capitalized_name$() {\n"
+    "  return result.get$capitalized_name$();\n"
+    "}\n"
+    "public Builder set$capitalized_name$($type$ value) {\n"
+    "  result.has$capitalized_name$ = true;\n"
+    "  result.$name$_ = value;\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder clear$capitalized_name$() {\n"
+    "  result.has$capitalized_name$ = false;\n"
+    "  result.$name$_ = $default$;\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (other.has$capitalized_name$()) {\n"
+    "  set$capitalized_name$(other.get$capitalized_name$());\n"
+    "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  // Nothing to do here for enum types.
+}
+
+void EnumFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "int rawValue = input.readEnum();\n"
+    "$type$ value = $type$.valueOf(rawValue);\n"
+    "if (value == null) {\n"
+    "  unknownFields.mergeVarintField($number$, rawValue);\n"
+    "} else {\n"
+    "  set$capitalized_name$(value);\n"
+    "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (has$capitalized_name$()) {\n"
+    "  output.writeEnum($number$, get$capitalized_name$().getNumber());\n"
+    "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (has$capitalized_name$()) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .computeEnumSize($number$, get$capitalized_name$().getNumber());\n"
+    "}\n");
+}
+
+string EnumFieldGenerator::GetBoxedType() const {
+  return ClassName(descriptor_->enum_type());
+}
+
+// ===================================================================
+
+RepeatedEnumFieldGenerator::
+RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetEnumVariables(descriptor, &variables_);
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+void RepeatedEnumFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private java.util.List<$type$> $name$_ =\n"
+    "  java.util.Collections.emptyList();\n"
+    "public java.util.List<$type$> get$capitalized_name$List() {\n"
+    "  return $name$_;\n"   // note:  unmodifiable list
+    "}\n"
+    "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
+    "public $type$ get$capitalized_name$(int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    // Note:  We return an unmodifiable list because otherwise the caller
+    //   could hold on to the returned list and modify it after the message
+    //   has been built, thus mutating the message which is supposed to be
+    //   immutable.
+    "public java.util.List<$type$> get$capitalized_name$List() {\n"
+    "  return java.util.Collections.unmodifiableList(result.$name$_);\n"
+    "}\n"
+    "public int get$capitalized_name$Count() {\n"
+    "  return result.get$capitalized_name$Count();\n"
+    "}\n"
+    "public $type$ get$capitalized_name$(int index) {\n"
+    "  return result.get$capitalized_name$(index);\n"
+    "}\n"
+    "public Builder set$capitalized_name$(int index, $type$ value) {\n"
+    "  result.$name$_.set(index, value);\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder add$capitalized_name$($type$ value) {\n"
+    "  if (result.$name$_.isEmpty()) {\n"
+    "    result.$name$_ = new java.util.ArrayList<$type$>();\n"
+    "  }\n"
+    "  result.$name$_.add(value);\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder addAll$capitalized_name$(\n"
+    "    java.lang.Iterable<? extends $type$> values) {\n"
+    "  if (result.$name$_.isEmpty()) {\n"
+    "    result.$name$_ = new java.util.ArrayList<$type$>();\n"
+    "  }\n"
+    "  super.addAll(values, result.$name$_);\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder clear$capitalized_name$() {\n"
+    "  result.$name$_ = java.util.Collections.emptyList();\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!other.$name$_.isEmpty()) {\n"
+    "  if (result.$name$_.isEmpty()) {\n"
+    "    result.$name$_ = new java.util.ArrayList<$type$>();\n"
+    "  }\n"
+    "  result.$name$_.addAll(other.$name$_);\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
+    "  result.$name$_ =\n"
+    "    java.util.Collections.unmodifiableList(result.$name$_);\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "int rawValue = input.readEnum();\n"
+    "$type$ value = $type$.valueOf(rawValue);\n"
+    "if (value == null) {\n"
+    "  unknownFields.mergeVarintField($number$, rawValue);\n"
+    "} else {\n"
+    "  add$capitalized_name$(value);\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for ($type$ element : get$capitalized_name$List()) {\n"
+    "  output.writeEnum($number$, element.getNumber());\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for ($type$ element : get$capitalized_name$List()) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .computeEnumSize($number$, element.getNumber());\n"
+    "}\n");
+}
+
+string RepeatedEnumFieldGenerator::GetBoxedType() const {
+  return ClassName(descriptor_->enum_type());
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_enum_field.h b/src/google/protobuf/compiler/java/java_enum_field.h
new file mode 100644
index 0000000..473ba61
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_enum_field.h
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class EnumFieldGenerator : public FieldGenerator {
+ public:
+  explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
+  ~EnumFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
+};
+
+class RepeatedEnumFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor);
+  ~RepeatedEnumFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc
new file mode 100644
index 0000000..1b637fa
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_extension.cc
@@ -0,0 +1,82 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {}
+
+ExtensionGenerator::~ExtensionGenerator() {}
+
+void ExtensionGenerator::Generate(io::Printer* printer) {
+  map<string, string> vars;
+  vars["name"] = UnderscoresToCamelCase(descriptor_);
+  vars["containing_type"] = ClassName(descriptor_->containing_type());
+  vars["index"] = SimpleItoa(descriptor_->index());
+
+  JavaType java_type = GetJavaType(descriptor_);
+  string singular_type;
+  switch (java_type) {
+    case JAVATYPE_MESSAGE:
+      vars["type"] = ClassName(descriptor_->message_type());
+      break;
+    case JAVATYPE_ENUM:
+      vars["type"] = ClassName(descriptor_->enum_type());
+      break;
+    default:
+      vars["type"] = BoxedPrimitiveTypeName(java_type);
+      break;
+  }
+
+  if (descriptor_->is_repeated()) {
+    printer->Print(vars,
+      "public static final\n"
+      "  com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+      "    $containing_type$,\n"
+      "    java.util.List<$type$>> $name$ =\n"
+      "      com.google.protobuf.GeneratedMessage\n"
+      "        .newRepeatedGeneratedExtension(\n"
+      "          getDescriptor().getExtensions().get($index$),\n"
+      "          $type$.class);\n");
+  } else {
+    printer->Print(vars,
+      "public static final\n"
+      "  com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+      "    $containing_type$,\n"
+      "    $type$> $name$ =\n"
+      "      com.google.protobuf.GeneratedMessage.newGeneratedExtension(\n"
+      "        getDescriptor().getExtensions().get($index$),\n"
+      "        $type$.class);\n");
+  }
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_extension.h b/src/google/protobuf/compiler/java/java_extension.h
new file mode 100644
index 0000000..9088fec
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_extension.h
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+  class FieldDescriptor;       // descriptor.h
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// Generates code for an extension, which may be within the scope of some
+// message or may be at file scope.  This is much simpler than FieldGenerator
+// since extensions are just simple identifiers with interesting types.
+class ExtensionGenerator {
+ public:
+  explicit ExtensionGenerator(const FieldDescriptor* descriptor);
+  ~ExtensionGenerator();
+
+  void Generate(io::Printer* printer);
+
+ private:
+  const FieldDescriptor* descriptor_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc
new file mode 100644
index 0000000..b7197ca
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_field.cc
@@ -0,0 +1,88 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_primitive_field.h>
+#include <google/protobuf/compiler/java/java_enum_field.h>
+#include <google/protobuf/compiler/java/java_message_field.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+FieldGenerator::~FieldGenerator() {}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
+  : descriptor_(descriptor),
+    field_generators_(
+      new scoped_ptr<FieldGenerator>[descriptor->field_count()]),
+    extension_generators_(
+      new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) {
+
+  // Construct all the FieldGenerators.
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    field_generators_[i].reset(MakeGenerator(descriptor->field(i)));
+  }
+  for (int i = 0; i < descriptor->extension_count(); i++) {
+    extension_generators_[i].reset(MakeGenerator(descriptor->extension(i)));
+  }
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
+  if (field->is_repeated()) {
+    switch (GetJavaType(field)) {
+      case JAVATYPE_MESSAGE:
+        return new RepeatedMessageFieldGenerator(field);
+      case JAVATYPE_ENUM:
+        return new RepeatedEnumFieldGenerator(field);
+      default:
+        return new RepeatedPrimitiveFieldGenerator(field);
+    }
+  } else {
+    switch (GetJavaType(field)) {
+      case JAVATYPE_MESSAGE:
+        return new MessageFieldGenerator(field);
+      case JAVATYPE_ENUM:
+        return new EnumFieldGenerator(field);
+      default:
+        return new PrimitiveFieldGenerator(field);
+    }
+  }
+}
+
+FieldGeneratorMap::~FieldGeneratorMap() {}
+
+const FieldGenerator& FieldGeneratorMap::get(
+    const FieldDescriptor* field) const {
+  GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+  return *field_generators_[field->index()];
+}
+
+const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
+  return *extension_generators_[index];
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h
new file mode 100644
index 0000000..ef47c73
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_field.h
@@ -0,0 +1,82 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class FieldGenerator {
+ public:
+  FieldGenerator() {}
+  virtual ~FieldGenerator();
+
+  virtual void GenerateMembers(io::Printer* printer) const = 0;
+  virtual void GenerateBuilderMembers(io::Printer* printer) const = 0;
+  virtual void GenerateMergingCode(io::Printer* printer) const = 0;
+  virtual void GenerateBuildingCode(io::Printer* printer) const = 0;
+  virtual void GenerateParsingCode(io::Printer* printer) const = 0;
+  virtual void GenerateSerializationCode(io::Printer* printer) const = 0;
+  virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
+
+  virtual string GetBoxedType() const = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
+};
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+class FieldGeneratorMap {
+ public:
+  explicit FieldGeneratorMap(const Descriptor* descriptor);
+  ~FieldGeneratorMap();
+
+  const FieldGenerator& get(const FieldDescriptor* field) const;
+  const FieldGenerator& get_extension(int index) const;
+
+ private:
+  const Descriptor* descriptor_;
+  scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
+  scoped_array<scoped_ptr<FieldGenerator> > extension_generators_;
+
+  static FieldGenerator* MakeGenerator(const FieldDescriptor* field);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc
new file mode 100644
index 0000000..e7e8618
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -0,0 +1,249 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_file.h>
+#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_service.h>
+#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_message.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+FileGenerator::FileGenerator(const FileDescriptor* file)
+  : file_(file),
+    java_package_(FileJavaPackage(file)),
+    classname_(FileClassName(file)) {}
+
+FileGenerator::~FileGenerator() {}
+
+bool FileGenerator::Validate(string* error) {
+  // Check that no class name matches the file's class name.  This is a common
+  // problem that leads to Java compile errors that can be hard to understand.
+  // It's especially bad when using the java_multiple_files, since we would
+  // end up overwriting the outer class with one of the inner ones.
+
+  bool found_conflict = false;
+  for (int i = 0; i < file_->enum_type_count() && !found_conflict; i++) {
+    if (file_->enum_type(i)->name() == classname_) {
+      found_conflict = true;
+    }
+  }
+  for (int i = 0; i < file_->message_type_count() && !found_conflict; i++) {
+    if (file_->message_type(i)->name() == classname_) {
+      found_conflict = true;
+    }
+  }
+  for (int i = 0; i < file_->service_count() && !found_conflict; i++) {
+    if (file_->service(i)->name() == classname_) {
+      found_conflict = true;
+    }
+  }
+
+  if (found_conflict) {
+    error->assign(file_->name());
+    error->append(
+      ": Cannot generate Java output because the file's outer class name, \"");
+    error->append(classname_);
+    error->append(
+      "\", matches the name of one of the types declared inside it.  "
+      "Please either rename the type or use the java_outer_classname "
+      "option to specify a different outer class name for the .proto file.");
+    return false;
+  }
+
+  return true;
+}
+
+void FileGenerator::Generate(io::Printer* printer) {
+  // We don't import anything because we refer to all classes by their
+  // fully-qualified names in the generated source.
+  printer->Print(
+    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
+    "\n");
+  if (!java_package_.empty()) {
+    printer->Print(
+      "package $package$;\n"
+      "\n",
+      "package", java_package_);
+  }
+  printer->Print(
+    "public final class $classname$ {\n"
+    "  private $classname$() {}\n",
+    "classname", classname_);
+  printer->Indent();
+
+  // -----------------------------------------------------------------
+
+  // Embed the descriptor.  We simply serialize the entire FileDescriptorProto
+  // and embed it as a string literal, which is parsed and built into real
+  // descriptors at initialization time.  We unfortunately have to put it in
+  // a string literal, not a byte array, because apparently using a literal
+  // byte array causes the Java compiler to generate *instructions* to
+  // initialize each and every byte of the array, e.g. as if you typed:
+  //   b[0] = 123; b[1] = 456; b[2] = 789;
+  // This makes huge bytecode files and can easily hit the compiler's internal
+  // code size limits (error "code to large").  String literals are apparently
+  // embedded raw, which is what we want.
+  FileDescriptorProto file_proto;
+  file_->CopyTo(&file_proto);
+  string file_data;
+  file_proto.SerializeToString(&file_data);
+
+  printer->Print(
+    "public static com.google.protobuf.Descriptors.FileDescriptor\n"
+    "    getDescriptor() {\n"
+    "  return descriptor;\n"
+    "}\n"
+    "private static final com.google.protobuf.Descriptors.FileDescriptor\n"
+    "    descriptor = buildDescriptor();\n"
+    "private static\n"
+    "    com.google.protobuf.Descriptors.FileDescriptor\n"
+    "    buildDescriptor() {\n"
+    "  java.lang.String descriptorData =\n");
+  printer->Indent();
+  printer->Indent();
+
+  // Only write 40 bytes per line.
+  static const int kBytesPerLine = 40;
+  for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+    if (i > 0) printer->Print(" +\n");
+    printer->Print("\"$data$\"",
+      "data", CEscape(file_data.substr(i, kBytesPerLine)));
+  }
+  printer->Print(";\n");
+
+  printer->Outdent();
+  printer->Print(
+    "try {\n"
+    "  return com.google.protobuf.Descriptors.FileDescriptor\n"
+    "    .internalBuildGeneratedFileFrom(descriptorData,\n"
+    "      new com.google.protobuf.Descriptors.FileDescriptor[] {\n");
+
+  for (int i = 0; i < file_->dependency_count(); i++) {
+    printer->Print(
+      "        $dependency$.getDescriptor(),\n",
+      "dependency", ClassName(file_->dependency(i)));
+  }
+
+  printer->Print(
+    "      });\n"
+    "} catch (Exception e) {\n"
+    "  throw new RuntimeException(\n"
+    "    \"Failed to parse protocol buffer descriptor for \" +\n"
+    "    \"\\\"$filename$\\\".\", e);\n"
+    "}\n",
+    "filename", file_->name());
+
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "\n");
+
+  // -----------------------------------------------------------------
+
+  if (!file_->options().java_multiple_files()) {
+    for (int i = 0; i < file_->enum_type_count(); i++) {
+      EnumGenerator(file_->enum_type(i)).Generate(printer);
+    }
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      MessageGenerator(file_->message_type(i)).Generate(printer);
+    }
+    for (int i = 0; i < file_->service_count(); i++) {
+      ServiceGenerator(file_->service(i)).Generate(printer);
+    }
+  }
+
+  // Extensions must be generated in the outer class since they are values,
+  // not classes.
+  for (int i = 0; i < file_->extension_count(); i++) {
+    ExtensionGenerator(file_->extension(i)).Generate(printer);
+  }
+
+  // Static variables.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    // TODO(kenton):  Reuse MessageGenerator objects?
+    MessageGenerator(file_->message_type(i)).GenerateStaticVariables(printer);
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+template<typename GeneratorClass, typename DescriptorClass>
+static void GenerateSibling(const string& package_dir,
+                            const string& java_package,
+                            const DescriptorClass* descriptor,
+                            OutputDirectory* output_directory,
+                            vector<string>* file_list) {
+  string filename = package_dir + descriptor->name() + ".java";
+  file_list->push_back(filename);
+
+  scoped_ptr<io::ZeroCopyOutputStream> output(
+    output_directory->Open(filename));
+  io::Printer printer(output.get(), '$');
+
+  printer.Print(
+    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
+    "\n");
+  if (!java_package.empty()) {
+    printer.Print(
+      "package $package$;\n"
+      "\n",
+      "package", java_package);
+  }
+
+  GeneratorClass(descriptor).Generate(&printer);
+}
+
+void FileGenerator::GenerateSiblings(const string& package_dir,
+                                     OutputDirectory* output_directory,
+                                     vector<string>* file_list) {
+  if (file_->options().java_multiple_files()) {
+    for (int i = 0; i < file_->enum_type_count(); i++) {
+      GenerateSibling<EnumGenerator>(package_dir, java_package_,
+                                     file_->enum_type(i),
+                                     output_directory, file_list);
+    }
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      GenerateSibling<MessageGenerator>(package_dir, java_package_,
+                                        file_->message_type(i),
+                                        output_directory, file_list);
+    }
+    for (int i = 0; i < file_->service_count(); i++) {
+      GenerateSibling<ServiceGenerator>(package_dir, java_package_,
+                                        file_->service(i),
+                                        output_directory, file_list);
+    }
+  }
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h
new file mode 100644
index 0000000..9eeec25
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_file.h
@@ -0,0 +1,78 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+  class FileDescriptor;        // descriptor.h
+  namespace io {
+    class Printer;             // printer.h
+  }
+  namespace compiler {
+    class OutputDirectory;     // code_generator.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class FileGenerator {
+ public:
+  explicit FileGenerator(const FileDescriptor* file);
+  ~FileGenerator();
+
+  // Checks for problems that would otherwise lead to cryptic compile errors.
+  // Returns true if there are no problems, or writes an error description to
+  // the given string and returns false otherwise.
+  bool Validate(string* error);
+
+  void Generate(io::Printer* printer);
+
+  // If we aren't putting everything into one file, this will write all the
+  // files other than the outer file (i.e. one for each message, enum, and
+  // service type).
+  void GenerateSiblings(const string& package_dir,
+                        OutputDirectory* output_directory,
+                        vector<string>* file_list);
+
+  const string& java_package() { return java_package_; }
+  const string& classname()    { return classname_;    }
+
+ private:
+  const FileDescriptor* file_;
+  string java_package_;
+  string classname_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc
new file mode 100644
index 0000000..89a32da
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_generator.cc
@@ -0,0 +1,133 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_generator.h>
+#include <google/protobuf/compiler/java/java_file.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+// Parses a set of comma-delimited name/value pairs, e.g.:
+//   "foo=bar,baz,qux=corge"
+// parses to the pairs:
+//   ("foo", "bar"), ("baz", ""), ("qux", "corge")
+void ParseOptions(const string& text, vector<pair<string, string> >* output) {
+  vector<string> parts;
+  SplitStringUsing(text, ",", &parts);
+
+  for (int i = 0; i < parts.size(); i++) {
+    string::size_type equals_pos = parts[i].find_first_of('=');
+    pair<string, string> value;
+    if (equals_pos == string::npos) {
+      value.first = parts[i];
+      value.second = "";
+    } else {
+      value.first = parts[i].substr(0, equals_pos);
+      value.second = parts[i].substr(equals_pos + 1);
+    }
+    output->push_back(value);
+  }
+}
+
+}  // namespace
+
+JavaGenerator::JavaGenerator() {}
+JavaGenerator::~JavaGenerator() {}
+
+bool JavaGenerator::Generate(const FileDescriptor* file,
+                             const string& parameter,
+                             OutputDirectory* output_directory,
+                             string* error) const {
+  vector<pair<string, string> > options;
+  ParseOptions(parameter, &options);
+
+  // -----------------------------------------------------------------
+  // parse generator options
+
+  // Name a file where we will write a list of generated file names, one
+  // per line.
+  string output_list_file;
+
+  for (int i = 0; i < options.size(); i++) {
+    if (options[i].first == "output_list_file") {
+      output_list_file = options[i].second;
+    } else {
+      *error = "Unknown generator option: " + options[i].first;
+      return false;
+    }
+  }
+
+
+  // -----------------------------------------------------------------
+
+
+  FileGenerator file_generator(file);
+  if (!file_generator.Validate(error)) {
+    return false;
+  }
+
+  string package_dir =
+    StringReplace(file_generator.java_package(), ".", "/", true);
+  if (!package_dir.empty()) package_dir += "/";
+
+  vector<string> all_files;
+
+  string java_filename = package_dir;
+  java_filename += file_generator.classname();
+  java_filename += ".java";
+  all_files.push_back(java_filename);
+
+  // Generate main java file.
+  scoped_ptr<io::ZeroCopyOutputStream> output(
+    output_directory->Open(java_filename));
+  io::Printer printer(output.get(), '$');
+  file_generator.Generate(&printer);
+
+  // Generate sibling files.
+  file_generator.GenerateSiblings(package_dir, output_directory, &all_files);
+
+  // Generate output list if requested.
+  if (!output_list_file.empty()) {
+    // Generate output list.  This is just a simple text file placed in a
+    // deterministic location which lists the .java files being generated.
+    scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
+      output_directory->Open(output_list_file));
+    io::Printer srclist_printer(srclist_raw_output.get(), '$');
+    for (int i = 0; i < all_files.size(); i++) {
+      srclist_printer.Print("$filename$\n", "filename", all_files[i]);
+    }
+  }
+
+  return true;
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_generator.h b/src/google/protobuf/compiler/java/java_generator.h
new file mode 100644
index 0000000..11886aa
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_generator.h
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Generates Java code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
+
+#include <string>
+#include <google/protobuf/compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// CodeGenerator implementation which generates Java code.  If you create your
+// own protocol compiler binary and you want it to support Java output, you
+// can do so by registering an instance of this CodeGenerator with the
+// CommandLineInterface in your main() function.
+class LIBPROTOC_EXPORT JavaGenerator : public CodeGenerator {
+ public:
+  JavaGenerator();
+  ~JavaGenerator();
+
+  // implements CodeGenerator ----------------------------------------
+  bool Generate(const FileDescriptor* file,
+                const string& parameter,
+                OutputDirectory* output_directory,
+                string* error) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc
new file mode 100644
index 0000000..4ba82c2
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_helpers.cc
@@ -0,0 +1,229 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <vector>
+
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+const char kThickSeparator[] =
+  "// ===================================================================\n";
+const char kThinSeparator[] =
+  "// -------------------------------------------------------------------\n";
+
+namespace {
+
+const char* kDefaultPackage = "";
+
+const string& FieldName(const FieldDescriptor* field) {
+  // Groups are hacky:  The name of the field is just the lower-cased name
+  // of the group type.  In Java, though, we would like to retain the original
+  // capitalization of the type name.
+  if (field->type() == FieldDescriptor::TYPE_GROUP) {
+    return field->message_type()->name();
+  } else {
+    return field->name();
+  }
+}
+
+string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) {
+  string result;
+  // Note:  I distrust ctype.h due to locales.
+  for (int i = 0; i < input.size(); i++) {
+    if ('a' <= input[i] && input[i] <= 'z') {
+      if (cap_next_letter) {
+        result += input[i] + ('A' - 'a');
+      } else {
+        result += input[i];
+      }
+      cap_next_letter = false;
+    } else if ('A' <= input[i] && input[i] <= 'Z') {
+      if (i == 0 && !cap_next_letter) {
+        // Force first letter to lower-case unless explicitly told to
+        // capitalize it.
+        result += input[i] + ('a' - 'A');
+      } else {
+        // Capital letters after the first are left as-is.
+        result += input[i];
+      }
+      cap_next_letter = false;
+    } else if ('0' <= input[i] && input[i] <= '9') {
+      result += input[i];
+      cap_next_letter = true;
+    } else {
+      cap_next_letter = true;
+    }
+  }
+  return result;
+}
+
+}  // namespace
+
+string UnderscoresToCamelCase(const FieldDescriptor* field) {
+  return UnderscoresToCamelCaseImpl(FieldName(field), false);
+}
+
+string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
+  return UnderscoresToCamelCaseImpl(FieldName(field), true);
+}
+
+string UnderscoresToCamelCase(const MethodDescriptor* method) {
+  return UnderscoresToCamelCaseImpl(method->name(), false);
+}
+
+string StripProto(const string& filename) {
+  if (HasSuffixString(filename, ".protodevel")) {
+    return StripSuffixString(filename, ".protodevel");
+  } else {
+    return StripSuffixString(filename, ".proto");
+  }
+}
+
+string FileClassName(const FileDescriptor* file) {
+  if (file->options().has_java_outer_classname()) {
+    return file->options().java_outer_classname();
+  } else {
+    string basename;
+    string::size_type last_slash = file->name().find_last_of('/');
+    if (last_slash == string::npos) {
+      basename = file->name();
+    } else {
+      basename = file->name().substr(last_slash + 1);
+    }
+    return UnderscoresToCamelCaseImpl(StripProto(basename), true);
+  }
+}
+
+string FileJavaPackage(const FileDescriptor* file) {
+  if (file->options().has_java_package()) {
+    return file->options().java_package();
+  } else {
+    string result = kDefaultPackage;
+    if (!file->package().empty()) {
+      if (!result.empty()) result += '.';
+      result += file->package();
+    }
+    return result;
+  }
+}
+
+string ToJavaName(const string& full_name, const FileDescriptor* file) {
+  string result;
+  if (file->options().java_multiple_files()) {
+    result = FileJavaPackage(file);
+  } else {
+    result = ClassName(file);
+  }
+  if (!result.empty()) {
+    result += '.';
+  }
+  if (file->package().empty()) {
+    result += full_name;
+  } else {
+    // Strip the proto package from full_name since we've replaced it with
+    // the Java package.
+    result += full_name.substr(file->package().size() + 1);
+  }
+  return result;
+}
+
+string ClassName(const FileDescriptor* descriptor) {
+  string result = FileJavaPackage(descriptor);
+  if (!result.empty()) result += '.';
+  result += FileClassName(descriptor);
+  return result;
+}
+
+JavaType GetJavaType(FieldDescriptor::Type field_type) {
+  switch (field_type) {
+    case FieldDescriptor::TYPE_INT32:
+    case FieldDescriptor::TYPE_UINT32:
+    case FieldDescriptor::TYPE_SINT32:
+    case FieldDescriptor::TYPE_FIXED32:
+    case FieldDescriptor::TYPE_SFIXED32:
+      return JAVATYPE_INT;
+
+    case FieldDescriptor::TYPE_INT64:
+    case FieldDescriptor::TYPE_UINT64:
+    case FieldDescriptor::TYPE_SINT64:
+    case FieldDescriptor::TYPE_FIXED64:
+    case FieldDescriptor::TYPE_SFIXED64:
+      return JAVATYPE_LONG;
+
+    case FieldDescriptor::TYPE_FLOAT:
+      return JAVATYPE_FLOAT;
+
+    case FieldDescriptor::TYPE_DOUBLE:
+      return JAVATYPE_DOUBLE;
+
+    case FieldDescriptor::TYPE_BOOL:
+      return JAVATYPE_BOOLEAN;
+
+    case FieldDescriptor::TYPE_STRING:
+      return JAVATYPE_STRING;
+
+    case FieldDescriptor::TYPE_BYTES:
+      return JAVATYPE_BYTES;
+
+    case FieldDescriptor::TYPE_ENUM:
+      return JAVATYPE_ENUM;
+
+    case FieldDescriptor::TYPE_GROUP:
+    case FieldDescriptor::TYPE_MESSAGE:
+      return JAVATYPE_MESSAGE;
+
+    // No default because we want the compiler to complain if any new
+    // types are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return JAVATYPE_INT;
+}
+
+const char* BoxedPrimitiveTypeName(JavaType type) {
+  switch (type) {
+    case JAVATYPE_INT    : return "java.lang.Integer";
+    case JAVATYPE_LONG   : return "java.lang.Long";
+    case JAVATYPE_FLOAT  : return "java.lang.Float";
+    case JAVATYPE_DOUBLE : return "java.lang.Double";
+    case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
+    case JAVATYPE_STRING : return "java.lang.String";
+    case JAVATYPE_BYTES  : return "com.google.protobuf.ByteString";
+    case JAVATYPE_ENUM   : return NULL;
+    case JAVATYPE_MESSAGE: return NULL;
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return NULL;
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h
new file mode 100644
index 0000000..7437633
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -0,0 +1,102 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
+
+#include <string>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// Commonly-used separator comments.  Thick is a line of '=', thin is a line
+// of '-'.
+extern const char kThickSeparator[];
+extern const char kThinSeparator[];
+
+// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
+// "fooBarBaz" or "FooBarBaz", respectively.
+string UnderscoresToCamelCase(const FieldDescriptor* field);
+string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
+
+// Similar, but for method names.  (Typically, this merely has the effect
+// of lower-casing the first letter of the name.)
+string UnderscoresToCamelCase(const MethodDescriptor* method);
+
+// Strips ".proto" or ".protodevel" from the end of a filename.
+string StripProto(const string& filename);
+
+// Gets the unqualified class name for the file.  Each .proto file becomes a
+// single Java class, with all its contents nested in that class.
+string FileClassName(const FileDescriptor* file);
+
+// Returns the file's Java package name.
+string FileJavaPackage(const FileDescriptor* file);
+
+// Converts the given fully-qualified name in the proto namespace to its
+// fully-qualified name in the Java namespace, given that it is in the given
+// file.
+string ToJavaName(const string& full_name, const FileDescriptor* file);
+
+// These return the fully-qualified class name corresponding to the given
+// descriptor.
+inline string ClassName(const Descriptor* descriptor) {
+  return ToJavaName(descriptor->full_name(), descriptor->file());
+}
+inline string ClassName(const EnumDescriptor* descriptor) {
+  return ToJavaName(descriptor->full_name(), descriptor->file());
+}
+inline string ClassName(const ServiceDescriptor* descriptor) {
+  return ToJavaName(descriptor->full_name(), descriptor->file());
+}
+string ClassName(const FileDescriptor* descriptor);
+
+enum JavaType {
+  JAVATYPE_INT,
+  JAVATYPE_LONG,
+  JAVATYPE_FLOAT,
+  JAVATYPE_DOUBLE,
+  JAVATYPE_BOOLEAN,
+  JAVATYPE_STRING,
+  JAVATYPE_BYTES,
+  JAVATYPE_ENUM,
+  JAVATYPE_MESSAGE
+};
+
+JavaType GetJavaType(FieldDescriptor::Type field_type);
+
+inline JavaType GetJavaType(const FieldDescriptor* field) {
+  return GetJavaType(field->type());
+}
+
+// Get the fully-qualified class name for a boxed primitive type, e.g.
+// "java.lang.Integer" for JAVATYPE_INT.  Returns NULL for enum and message
+// types.
+const char* BoxedPrimitiveTypeName(JavaType type);
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
new file mode 100644
index 0000000..ebba1f7
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -0,0 +1,722 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <algorithm>
+#include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/compiler/java/java_message.h>
+#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+
+namespace {
+
+void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
+  // Print the field's proto-syntax definition as a comment.  We don't want to
+  // print group bodies so we cut off after the first line.
+  string def = field->DebugString();
+  printer->Print("// $def$\n",
+    "def", def.substr(0, def.find_first_of('\n')));
+}
+
+struct FieldOrderingByNumber {
+  inline bool operator()(const FieldDescriptor* a,
+                         const FieldDescriptor* b) const {
+    return a->number() < b->number();
+  }
+};
+
+struct ExtensionRangeOrdering {
+  bool operator()(const Descriptor::ExtensionRange* a,
+                  const Descriptor::ExtensionRange* b) const {
+    return a->start < b->start;
+  }
+};
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it.
+const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
+  const FieldDescriptor** fields =
+    new const FieldDescriptor*[descriptor->field_count()];
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    fields[i] = descriptor->field(i);
+  }
+  sort(fields, fields + descriptor->field_count(),
+       FieldOrderingByNumber());
+  return fields;
+}
+
+// Get an identifier that uniquely identifies this type within the file.
+// This is used to declare static variables related to this type at the
+// outermost file scope.
+string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
+  return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
+}
+
+// Returns true if the message type has any required fields.  If it doesn't,
+// we can optimize out calls to its isInitialized() method.
+//
+// already_seen is used to avoid checking the same type multiple times
+// (and also to protect against recursion).
+static bool HasRequiredFields(
+    const Descriptor* type,
+    hash_set<const Descriptor*>* already_seen) {
+  if (already_seen->count(type) > 0) {
+    // The type is already in cache.  This means that either:
+    // a. The type has no required fields.
+    // b. We are in the midst of checking if the type has required fields,
+    //    somewhere up the stack.  In this case, we know that if the type
+    //    has any required fields, they'll be found when we return to it,
+    //    and the whole call to HasRequiredFields() will return true.
+    //    Therefore, we don't have to check if this type has required fields
+    //    here.
+    return false;
+  }
+  already_seen->insert(type);
+
+  // If the type has extensions, an extension with message type could contain
+  // required fields, so we have to be conservative and assume such an
+  // extension exists.
+  if (type->extension_range_count() > 0) return true;
+
+  for (int i = 0; i < type->field_count(); i++) {
+    const FieldDescriptor* field = type->field(i);
+    if (field->is_required()) {
+      return true;
+    }
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (HasRequiredFields(field->message_type(), already_seen)) {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+static bool HasRequiredFields(const Descriptor* type) {
+  hash_set<const Descriptor*> already_seen;
+  return HasRequiredFields(type, &already_seen);
+}
+
+}  // namespace
+
+// ===================================================================
+
+MessageGenerator::MessageGenerator(const Descriptor* descriptor)
+  : descriptor_(descriptor),
+    field_generators_(descriptor) {
+}
+
+MessageGenerator::~MessageGenerator() {}
+
+void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
+  // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
+  // used in the construction of descriptors, we have a tricky bootstrapping
+  // problem.  To help control static initialization order, we make sure all
+  // descriptors and other static data that depends on them are members of
+  // the outermost class in the file.  This way, they will be initialized in
+  // a deterministic order.
+
+  map<string, string> vars;
+  vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+  vars["index"] = SimpleItoa(descriptor_->index());
+  vars["classname"] = ClassName(descriptor_);
+  if (descriptor_->containing_type() != NULL) {
+    vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
+  }
+  if (descriptor_->file()->options().java_multiple_files()) {
+    // We can only make these package-private since the classes that use them
+    // are in separate files.
+    vars["private"] = "";
+  } else {
+    vars["private"] = "private ";
+  }
+
+  // The descriptor for this type.
+  if (descriptor_->containing_type() == NULL) {
+    printer->Print(vars,
+      "$private$static final com.google.protobuf.Descriptors.Descriptor\n"
+      "  internal_$identifier$_descriptor =\n"
+      "    getDescriptor().getMessageTypes().get($index$);\n");
+  } else {
+    printer->Print(vars,
+      "$private$static final com.google.protobuf.Descriptors.Descriptor\n"
+      "  internal_$identifier$_descriptor =\n"
+      "    internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
+  }
+
+  // And the FieldAccessorTable.
+  printer->Print(vars,
+    "$private$static\n"
+    "  com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+    "    internal_$identifier$_fieldAccessorTable = new\n"
+    "      com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
+    "        internal_$identifier$_descriptor,\n"
+    "        new java.lang.String[] { ");
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    printer->Print(
+      "\"$field_name$\", ",
+      "field_name",
+        UnderscoresToCapitalizedCamelCase(descriptor_->field(i)));
+  }
+  printer->Print("},\n"
+    "        $classname$.class,\n"
+    "        $classname$.Builder.class);\n",
+    "classname", ClassName(descriptor_));
+
+  // Generate static members for all nested types.
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    // TODO(kenton):  Reuse MessageGenerator objects?
+    MessageGenerator(descriptor_->nested_type(i))
+      .GenerateStaticVariables(printer);
+  }
+}
+
+void MessageGenerator::Generate(io::Printer* printer) {
+  bool is_own_file =
+    descriptor_->containing_type() == NULL &&
+    descriptor_->file()->options().java_multiple_files();
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "public $static$ final class $classname$ extends\n"
+      "    com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
+      "      $classname$> {\n",
+      "static", is_own_file ? "" : "static",
+      "classname", descriptor_->name());
+  } else {
+    printer->Print(
+      "public $static$ final class $classname$ extends\n"
+      "    com.google.protobuf.GeneratedMessage {\n",
+      "static", is_own_file ? "" : "static",
+      "classname", descriptor_->name());
+  }
+  printer->Indent();
+  printer->Print(
+    "// Use $classname$.newBuilder() to construct.\n"
+    "private $classname$() {}\n"
+    "\n"
+    "private static final $classname$ defaultInstance = new $classname$();\n"
+    "public static $classname$ getDefaultInstance() {\n"
+    "  return defaultInstance;\n"
+    "}\n"
+    "\n"
+    "public $classname$ getDefaultInstanceForType() {\n"
+    "  return defaultInstance;\n"
+    "}\n"
+    "\n",
+    "classname", descriptor_->name());
+  printer->Print(
+    "public static final com.google.protobuf.Descriptors.Descriptor\n"
+    "    getDescriptor() {\n"
+    "  return $fileclass$.internal_$identifier$_descriptor;\n"
+    "}\n"
+    "\n"
+    "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+    "    internalGetFieldAccessorTable() {\n"
+    "  return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
+    "}\n"
+    "\n",
+    "fileclass", ClassName(descriptor_->file()),
+    "identifier", UniqueFileScopeIdentifier(descriptor_));
+
+  // Nested types and extensions
+  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+    EnumGenerator(descriptor_->enum_type(i)).Generate(printer);
+  }
+
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    MessageGenerator(descriptor_->nested_type(i)).Generate(printer);
+  }
+
+  for (int i = 0; i < descriptor_->extension_count(); i++) {
+    ExtensionGenerator(descriptor_->extension(i)).Generate(printer);
+  }
+
+  // Fields
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    PrintFieldComment(printer, descriptor_->field(i));
+    field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
+    printer->Print("\n");
+  }
+
+  if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+    GenerateIsInitialized(printer);
+    GenerateMessageSerializationMethods(printer);
+  }
+
+  GenerateParseFromMethods(printer);
+  GenerateBuilder(printer);
+}
+
+// ===================================================================
+
+void MessageGenerator::
+GenerateMessageSerializationMethods(io::Printer* printer) {
+  scoped_array<const FieldDescriptor*> sorted_fields(
+    SortFieldsByNumber(descriptor_));
+
+  vector<const Descriptor::ExtensionRange*> sorted_extensions;
+  for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+    sorted_extensions.push_back(descriptor_->extension_range(i));
+  }
+  sort(sorted_extensions.begin(), sorted_extensions.end(),
+       ExtensionRangeOrdering());
+
+  printer->Print(
+    "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
+    "                    throws java.io.IOException {\n");
+  printer->Indent();
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "com.google.protobuf.GeneratedMessage.ExtendableMessage\n"
+      "  .ExtensionWriter extensionWriter = newExtensionWriter();\n");
+  }
+
+  // Merge the fields and the extension ranges, both sorted by field number.
+  for (int i = 0, j = 0;
+       i < descriptor_->field_count() || j < sorted_extensions.size();
+       ) {
+    if (i == descriptor_->field_count()) {
+      GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
+    } else if (j == sorted_extensions.size()) {
+      GenerateSerializeOneField(printer, sorted_fields[i++]);
+    } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
+      GenerateSerializeOneField(printer, sorted_fields[i++]);
+    } else {
+      GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
+    }
+  }
+
+  if (descriptor_->options().message_set_wire_format()) {
+    printer->Print(
+      "getUnknownFields().writeAsMessageSetTo(output);\n");
+  } else {
+    printer->Print(
+      "getUnknownFields().writeTo(output);\n");
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "\n"
+    "private int memoizedSerializedSize = -1;\n"
+    "public int getSerializedSize() {\n"
+    "  int size = memoizedSerializedSize;\n"
+    "  if (size != -1) return size;\n"
+    "\n"
+    "  size = 0;\n");
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
+  }
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "size += extensionsSerializedSize();\n");
+  }
+
+  if (descriptor_->options().message_set_wire_format()) {
+    printer->Print(
+      "size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
+  } else {
+    printer->Print(
+      "size += getUnknownFields().getSerializedSize();\n");
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "  memoizedSerializedSize = size;\n"
+    "  return size;\n"
+    "}\n"
+    "\n");
+}
+
+void MessageGenerator::
+GenerateParseFromMethods(io::Printer* printer) {
+  // Note:  These are separate from GenerateMessageSerializationMethods()
+  //   because they need to be generated even for messages that are optimized
+  //   for code size.
+  printer->Print(
+    "public static $classname$ parseFrom(\n"
+    "    com.google.protobuf.ByteString data)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return newBuilder().mergeFrom(data).buildParsed();\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    com.google.protobuf.ByteString data,\n"
+    "    com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return newBuilder().mergeFrom(data, extensionRegistry)\n"
+    "           .buildParsed();\n"
+    "}\n"
+    "public static $classname$ parseFrom(byte[] data)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return newBuilder().mergeFrom(data).buildParsed();\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    byte[] data,\n"
+    "    com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return newBuilder().mergeFrom(data, extensionRegistry)\n"
+    "           .buildParsed();\n"
+    "}\n"
+    "public static $classname$ parseFrom(java.io.InputStream input)\n"
+    "    throws java.io.IOException {\n"
+    "  return newBuilder().mergeFrom(input).buildParsed();\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    java.io.InputStream input,\n"
+    "    com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+    "    throws java.io.IOException {\n"
+    "  return newBuilder().mergeFrom(input, extensionRegistry)\n"
+    "           .buildParsed();\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    com.google.protobuf.CodedInputStream input)\n"
+    "    throws java.io.IOException {\n"
+    "  return newBuilder().mergeFrom(input).buildParsed();\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    com.google.protobuf.CodedInputStream input,\n"
+    "    com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+    "    throws java.io.IOException {\n"
+    "  return newBuilder().mergeFrom(input, extensionRegistry)\n"
+    "           .buildParsed();\n"
+    "}\n"
+    "\n",
+    "classname", ClassName(descriptor_));
+}
+
+void MessageGenerator::GenerateSerializeOneField(
+    io::Printer* printer, const FieldDescriptor* field) {
+  field_generators_.get(field).GenerateSerializationCode(printer);
+}
+
+void MessageGenerator::GenerateSerializeOneExtensionRange(
+    io::Printer* printer, const Descriptor::ExtensionRange* range) {
+  printer->Print(
+    "extensionWriter.writeUntil($end$, output);\n",
+    "end", SimpleItoa(range->end));
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateBuilder(io::Printer* printer) {
+  printer->Print(
+    "public static Builder newBuilder() { return new Builder(); }\n"
+    "public Builder newBuilderForType() { return new Builder(); }\n"
+    "public static Builder newBuilder($classname$ prototype) {\n"
+    "  return new Builder().mergeFrom(prototype);\n"
+    "}\n"
+    "\n",
+    "classname", ClassName(descriptor_));
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "public static final class Builder extends\n"
+      "    com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
+      "      $classname$, Builder> {\n",
+      "classname", ClassName(descriptor_));
+  } else {
+    printer->Print(
+      "public static final class Builder extends\n"
+      "    com.google.protobuf.GeneratedMessage.Builder<Builder> {\n",
+      "classname", ClassName(descriptor_));
+  }
+  printer->Indent();
+
+  GenerateCommonBuilderMethods(printer);
+
+  if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+    GenerateBuilderParsingMethods(printer);
+  }
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    printer->Print("\n");
+    PrintFieldComment(printer, descriptor_->field(i));
+    field_generators_.get(descriptor_->field(i))
+                     .GenerateBuilderMembers(printer);
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
+  printer->Print(
+    "// Construct using $classname$.newBuilder()\n"
+    "private Builder() {}\n"
+    "\n"
+    "$classname$ result = new $classname$();\n"
+    "\n"
+    "protected $classname$ internalGetResult() {\n"
+    "  return result;\n"
+    "}\n"
+    "\n"
+    "public Builder clear() {\n"
+    "  result = new $classname$();\n"
+    "  return this;\n"
+    "}\n"
+    "\n"
+    "public Builder clone() {\n"
+    "  return new Builder().mergeFrom(result);\n"
+    "}\n"
+    "\n"
+    "public com.google.protobuf.Descriptors.Descriptor\n"
+    "    getDescriptorForType() {\n"
+    "  return $classname$.getDescriptor();\n"
+    "}\n"
+    "\n"
+    "public $classname$ getDefaultInstanceForType() {\n"
+    "  return $classname$.getDefaultInstance();\n"
+    "}\n"
+    "\n",
+    "classname", ClassName(descriptor_));
+
+  // -----------------------------------------------------------------
+
+  printer->Print(
+    "public $classname$ build() {\n"
+    "  if (!isInitialized()) {\n"
+    "    throw new com.google.protobuf.UninitializedMessageException(\n"
+    "      result);\n"
+    "  }\n"
+    "  return buildPartial();\n"
+    "}\n"
+    "\n"
+    "private $classname$ buildParsed()\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  if (!isInitialized()) {\n"
+    "    throw new com.google.protobuf.UninitializedMessageException(\n"
+    "      result).asInvalidProtocolBufferException();\n"
+    "  }\n"
+    "  return buildPartial();\n"
+    "}\n"
+    "\n"
+    "public $classname$ buildPartial() {\n",
+    "classname", ClassName(descriptor_));
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "  $classname$ returnMe = result;\n"
+    "  result = null;\n"
+    "  return returnMe;\n"
+    "}\n"
+    "\n",
+    "classname", ClassName(descriptor_));
+
+  // -----------------------------------------------------------------
+
+  if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
+    printer->Print(
+      "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
+      "  if (other instanceof $classname$) {\n"
+      "    return mergeFrom(($classname$)other);\n"
+      "  } else {\n"
+      "    super.mergeFrom(other);\n"
+      "    return this;\n"
+      "  }\n"
+      "}\n"
+      "\n"
+      "public Builder mergeFrom($classname$ other) {\n"
+      // Optimization:  If other is the default instance, we know none of its
+      //   fields are set so we can skip the merge.
+      "  if (other == $classname$.getDefaultInstance()) return this;\n",
+      "classname", ClassName(descriptor_));
+    printer->Indent();
+
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      field_generators_.get(descriptor_->field(i)).GenerateMergingCode(printer);
+    }
+
+    printer->Outdent();
+    printer->Print(
+      "  this.mergeUnknownFields(other.getUnknownFields());\n"
+      "  return this;\n"
+      "}\n"
+      "\n");
+  }
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
+  scoped_array<const FieldDescriptor*> sorted_fields(
+    SortFieldsByNumber(descriptor_));
+
+  printer->Print(
+    "public Builder mergeFrom(\n"
+    "    com.google.protobuf.CodedInputStream input)\n"
+    "    throws java.io.IOException {\n"
+    "  return mergeFrom(input,\n"
+    "    com.google.protobuf.ExtensionRegistry.getEmptyRegistry());\n"
+    "}\n"
+    "\n"
+    "public Builder mergeFrom(\n"
+    "    com.google.protobuf.CodedInputStream input,\n"
+    "    com.google.protobuf.ExtensionRegistry extensionRegistry)\n"
+    "    throws java.io.IOException {\n");
+  printer->Indent();
+
+  printer->Print(
+    "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
+    "  com.google.protobuf.UnknownFieldSet.newBuilder(\n"
+    "    this.getUnknownFields());\n"
+    "while (true) {\n");
+  printer->Indent();
+
+  printer->Print(
+    "int tag = input.readTag();\n"
+    "switch (tag) {\n");
+  printer->Indent();
+
+  printer->Print(
+    "case 0:\n"          // zero signals EOF / limit reached
+    "  this.setUnknownFields(unknownFields.build());\n"
+    "  return this;\n"
+    "default: {\n"
+    "  if (!parseUnknownField(input, unknownFields,\n"
+    "                         extensionRegistry, tag)) {\n"
+    "    this.setUnknownFields(unknownFields.build());\n"
+    "    return this;\n"   // it's an endgroup tag
+    "  }\n"
+    "  break;\n"
+    "}\n");
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = sorted_fields[i];
+    uint32 tag = WireFormat::MakeTag(field->number(),
+      WireFormat::WireTypeForFieldType(field->type()));
+
+    printer->Print(
+      "case $tag$: {\n",
+      "tag", SimpleItoa(tag));
+    printer->Indent();
+
+    field_generators_.get(field).GenerateParsingCode(printer);
+
+    printer->Outdent();
+    printer->Print(
+      "  break;\n"
+      "}\n");
+  }
+
+  printer->Outdent();
+  printer->Outdent();
+  printer->Outdent();
+  printer->Print(
+    "    }\n"     // switch (tag)
+    "  }\n"       // while (true)
+    "}\n"
+    "\n");
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
+  printer->Print(
+    "public final boolean isInitialized() {\n");
+  printer->Indent();
+
+  // Check that all required fields in this message are set.
+  // TODO(kenton):  We can optimize this when we switch to putting all the
+  //   "has" fields into a single bitfield.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    if (field->is_required()) {
+      printer->Print(
+        "if (!has$name$) return false;\n",
+        "name", UnderscoresToCapitalizedCamelCase(field));
+    }
+  }
+
+  // Now check that all embedded messages are initialized.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+        HasRequiredFields(field->message_type())) {
+      switch (field->label()) {
+        case FieldDescriptor::LABEL_REQUIRED:
+          printer->Print(
+            "if (!get$name$().isInitialized()) return false;\n",
+            "type", ClassName(field->message_type()),
+            "name", UnderscoresToCapitalizedCamelCase(field));
+          break;
+        case FieldDescriptor::LABEL_OPTIONAL:
+          printer->Print(
+            "if (has$name$()) {\n"
+            "  if (!get$name$().isInitialized()) return false;\n"
+            "}\n",
+            "type", ClassName(field->message_type()),
+            "name", UnderscoresToCapitalizedCamelCase(field));
+          break;
+        case FieldDescriptor::LABEL_REPEATED:
+          printer->Print(
+            "for ($type$ element : get$name$List()) {\n"
+            "  if (!element.isInitialized()) return false;\n"
+            "}\n",
+            "type", ClassName(field->message_type()),
+            "name", UnderscoresToCapitalizedCamelCase(field));
+          break;
+      }
+    }
+  }
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "if (!extensionsAreInitialized()) return false;\n");
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "  return true;\n"
+    "}\n"
+    "\n");
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h
new file mode 100644
index 0000000..d9f8798
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_message.h
@@ -0,0 +1,76 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class MessageGenerator {
+ public:
+  explicit MessageGenerator(const Descriptor* descriptor);
+  ~MessageGenerator();
+
+  // All static variables have to be declared at the top-level of the file
+  // so that we can control initialization order, which is important for
+  // DescriptorProto bootstrapping to work.
+  void GenerateStaticVariables(io::Printer* printer);
+
+  // Generate the class itself.
+  void Generate(io::Printer* printer);
+
+ private:
+  void GenerateMessageSerializationMethods(io::Printer* printer);
+  void GenerateParseFromMethods(io::Printer* printer);
+  void GenerateSerializeOneField(io::Printer* printer,
+                                 const FieldDescriptor* field);
+  void GenerateSerializeOneExtensionRange(
+      io::Printer* printer, const Descriptor::ExtensionRange* range);
+
+  void GenerateBuilder(io::Printer* printer);
+  void GenerateCommonBuilderMethods(io::Printer* printer);
+  void GenerateBuilderParsingMethods(io::Printer* printer);
+  void GenerateIsInitialized(io::Printer* printer);
+
+  const Descriptor* descriptor_;
+  FieldGeneratorMap field_generators_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc
new file mode 100644
index 0000000..16ddb0d
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -0,0 +1,302 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_message_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+// TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
+//   repeat code between this and the other field types.
+void SetMessageVariables(const FieldDescriptor* descriptor,
+                         map<string, string>* variables) {
+  (*variables)["name"] =
+    UnderscoresToCamelCase(descriptor);
+  (*variables)["capitalized_name"] =
+    UnderscoresToCapitalizedCamelCase(descriptor);
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["type"] = ClassName(descriptor->message_type());
+  (*variables)["group_or_message"] =
+    (descriptor->type() == FieldDescriptor::TYPE_GROUP) ?
+    "Group" : "Message";
+}
+
+}  // namespace
+
+// ===================================================================
+
+MessageFieldGenerator::
+MessageFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetMessageVariables(descriptor, &variables_);
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {}
+
+void MessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private boolean has$capitalized_name$;\n"
+    "private $type$ $name$_ = $type$.getDefaultInstance();\n"
+    "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
+    "public $type$ get$capitalized_name$() { return $name$_; }\n");
+}
+
+void MessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "public boolean has$capitalized_name$() {\n"
+    "  return result.has$capitalized_name$();\n"
+    "}\n"
+    "public $type$ get$capitalized_name$() {\n"
+    "  return result.get$capitalized_name$();\n"
+    "}\n"
+    "public Builder set$capitalized_name$($type$ value) {\n"
+    "  result.has$capitalized_name$ = true;\n"
+    "  result.$name$_ = value;\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder set$capitalized_name$($type$.Builder builderForValue) {\n"
+    "  result.has$capitalized_name$ = true;\n"
+    "  result.$name$_ = builderForValue.build();\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder merge$capitalized_name$($type$ value) {\n"
+    "  if (result.has$capitalized_name$() &&\n"
+    "      result.$name$_ != $type$.getDefaultInstance()) {\n"
+    "    result.$name$_ =\n"
+    "      $type$.newBuilder(result.$name$_).mergeFrom(value).buildPartial();\n"
+    "  } else {\n"
+    "    result.$name$_ = value;\n"
+    "  }\n"
+    "  result.has$capitalized_name$ = true;\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder clear$capitalized_name$() {\n"
+    "  result.has$capitalized_name$ = false;\n"
+    "  result.$name$_ = $type$.getDefaultInstance();\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (other.has$capitalized_name$()) {\n"
+    "  merge$capitalized_name$(other.get$capitalized_name$());\n"
+    "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  // Nothing to do for singular fields.
+}
+
+void MessageFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$type$.Builder subBuilder = $type$.newBuilder();\n"
+    "if (has$capitalized_name$()) {\n"
+    "  subBuilder.mergeFrom(get$capitalized_name$());\n"
+    "}\n");
+
+  if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
+    printer->Print(variables_,
+      "input.readGroup($number$, subBuilder, extensionRegistry);\n");
+  } else {
+    printer->Print(variables_,
+      "input.readMessage(subBuilder, extensionRegistry);\n");
+  }
+
+  printer->Print(variables_,
+    "set$capitalized_name$(subBuilder.buildPartial());\n");
+}
+
+void MessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (has$capitalized_name$()) {\n"
+    "  output.write$group_or_message$($number$, get$capitalized_name$());\n"
+    "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (has$capitalized_name$()) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
+    "}\n");
+}
+
+string MessageFieldGenerator::GetBoxedType() const {
+  return ClassName(descriptor_->message_type());
+}
+
+// ===================================================================
+
+RepeatedMessageFieldGenerator::
+RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetMessageVariables(descriptor, &variables_);
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+
+void RepeatedMessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private java.util.List<$type$> $name$_ =\n"
+    "  java.util.Collections.emptyList();\n"
+    "public java.util.List<$type$> get$capitalized_name$List() {\n"
+    "  return $name$_;\n"   // note:  unmodifiable list
+    "}\n"
+    "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
+    "public $type$ get$capitalized_name$(int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    // Note:  We return an unmodifiable list because otherwise the caller
+    //   could hold on to the returned list and modify it after the message
+    //   has been built, thus mutating the message which is supposed to be
+    //   immutable.
+    "public java.util.List<$type$> get$capitalized_name$List() {\n"
+    "  return java.util.Collections.unmodifiableList(result.$name$_);\n"
+    "}\n"
+    "public int get$capitalized_name$Count() {\n"
+    "  return result.get$capitalized_name$Count();\n"
+    "}\n"
+    "public $type$ get$capitalized_name$(int index) {\n"
+    "  return result.get$capitalized_name$(index);\n"
+    "}\n"
+    "public Builder set$capitalized_name$(int index, $type$ value) {\n"
+    "  result.$name$_.set(index, value);\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder set$capitalized_name$(int index, "
+      "$type$.Builder builderForValue) {\n"
+    "  result.$name$_.set(index, builderForValue.build());\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder add$capitalized_name$($type$ value) {\n"
+    "  if (result.$name$_.isEmpty()) {\n"
+    "    result.$name$_ = new java.util.ArrayList<$type$>();\n"
+    "  }\n"
+    "  result.$name$_.add(value);\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder add$capitalized_name$($type$.Builder builderForValue) {\n"
+    "  if (result.$name$_.isEmpty()) {\n"
+    "    result.$name$_ = new java.util.ArrayList<$type$>();\n"
+    "  }\n"
+    "  result.$name$_.add(builderForValue.build());\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder addAll$capitalized_name$(\n"
+    "    java.lang.Iterable<? extends $type$> values) {\n"
+    "  if (result.$name$_.isEmpty()) {\n"
+    "    result.$name$_ = new java.util.ArrayList<$type$>();\n"
+    "  }\n"
+    "  super.addAll(values, result.$name$_);\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder clear$capitalized_name$() {\n"
+    "  result.$name$_ = java.util.Collections.emptyList();\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!other.$name$_.isEmpty()) {\n"
+    "  if (result.$name$_.isEmpty()) {\n"
+    "    result.$name$_ = new java.util.ArrayList<$type$>();\n"
+    "  }\n"
+    "  result.$name$_.addAll(other.$name$_);\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
+    "  result.$name$_ =\n"
+    "    java.util.Collections.unmodifiableList(result.$name$_);\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$type$.Builder subBuilder = $type$.newBuilder();\n");
+
+  if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
+    printer->Print(variables_,
+      "input.readGroup($number$, subBuilder, extensionRegistry);\n");
+  } else {
+    printer->Print(variables_,
+      "input.readMessage(subBuilder, extensionRegistry);\n");
+  }
+
+  printer->Print(variables_,
+    "add$capitalized_name$(subBuilder.buildPartial());\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for ($type$ element : get$capitalized_name$List()) {\n"
+    "  output.write$group_or_message$($number$, element);\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for ($type$ element : get$capitalized_name$List()) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .compute$group_or_message$Size($number$, element);\n"
+    "}\n");
+}
+
+string RepeatedMessageFieldGenerator::GetBoxedType() const {
+  return ClassName(descriptor_->message_type());
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_message_field.h b/src/google/protobuf/compiler/java/java_message_field.h
new file mode 100644
index 0000000..52cf7d1
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_message_field.h
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class MessageFieldGenerator : public FieldGenerator {
+ public:
+  explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
+  ~MessageFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
+};
+
+class RepeatedMessageFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
+  ~RepeatedMessageFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
new file mode 100644
index 0000000..9138f2c
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -0,0 +1,365 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_primitive_field.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+const char* PrimitiveTypeName(JavaType type) {
+  switch (type) {
+    case JAVATYPE_INT    : return "int";
+    case JAVATYPE_LONG   : return "long";
+    case JAVATYPE_FLOAT  : return "float";
+    case JAVATYPE_DOUBLE : return "double";
+    case JAVATYPE_BOOLEAN: return "boolean";
+    case JAVATYPE_STRING : return "java.lang.String";
+    case JAVATYPE_BYTES  : return "com.google.protobuf.ByteString";
+    case JAVATYPE_ENUM   : return NULL;
+    case JAVATYPE_MESSAGE: return NULL;
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return NULL;
+}
+
+const char* GetCapitalizedType(const FieldDescriptor* field) {
+  switch (field->type()) {
+    case FieldDescriptor::TYPE_INT32   : return "Int32"   ;
+    case FieldDescriptor::TYPE_UINT32  : return "UInt32"  ;
+    case FieldDescriptor::TYPE_SINT32  : return "SInt32"  ;
+    case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ;
+    case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
+    case FieldDescriptor::TYPE_INT64   : return "Int64"   ;
+    case FieldDescriptor::TYPE_UINT64  : return "UInt64"  ;
+    case FieldDescriptor::TYPE_SINT64  : return "SInt64"  ;
+    case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ;
+    case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
+    case FieldDescriptor::TYPE_FLOAT   : return "Float"   ;
+    case FieldDescriptor::TYPE_DOUBLE  : return "Double"  ;
+    case FieldDescriptor::TYPE_BOOL    : return "Bool"    ;
+    case FieldDescriptor::TYPE_STRING  : return "String"  ;
+    case FieldDescriptor::TYPE_BYTES   : return "Bytes"   ;
+    case FieldDescriptor::TYPE_ENUM    : return "Enum"    ;
+    case FieldDescriptor::TYPE_GROUP   : return "Group"   ;
+    case FieldDescriptor::TYPE_MESSAGE : return "Message" ;
+
+    // No default because we want the compiler to complain if any new
+    // types are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return NULL;
+}
+
+bool AllPrintableAscii(const string& text) {
+  // Cannot use isprint() because it's locale-specific.  :(
+  for (int i = 0; i < text.size(); i++) {
+    if ((text[i] < 0x20) || text[i] >= 0x7F) {
+      return false;
+    }
+  }
+  return true;
+}
+
+string DefaultValue(const FieldDescriptor* field) {
+  // Switch on cpp_type since we need to know which default_value_* method
+  // of FieldDescriptor to call.
+  switch (field->cpp_type()) {
+    case FieldDescriptor::CPPTYPE_INT32:
+      return SimpleItoa(field->default_value_int32());
+    case FieldDescriptor::CPPTYPE_UINT32:
+      // Need to print as a signed int since Java has no unsigned.
+      return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
+    case FieldDescriptor::CPPTYPE_INT64:
+      return SimpleItoa(field->default_value_int64()) + "L";
+    case FieldDescriptor::CPPTYPE_UINT64:
+      return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
+             "L";
+    case FieldDescriptor::CPPTYPE_DOUBLE:
+      return SimpleDtoa(field->default_value_double()) + "D";
+    case FieldDescriptor::CPPTYPE_FLOAT:
+      return SimpleFtoa(field->default_value_float()) + "F";
+    case FieldDescriptor::CPPTYPE_BOOL:
+      return field->default_value_bool() ? "true" : "false";
+    case FieldDescriptor::CPPTYPE_STRING: {
+      bool isBytes = field->type() == FieldDescriptor::TYPE_BYTES;
+
+      if (!isBytes && AllPrintableAscii(field->default_value_string())) {
+        // All chars are ASCII and printable.  In this case CEscape() works
+        // fine (it will only escape quotes and backslashes).
+        // Note:  If this "optimization" is removed, DescriptorProtos will
+        //   no longer be able to initialize itself due to bootstrapping
+        //   problems.
+        return "\"" + CEscape(field->default_value_string()) + "\"";
+      }
+
+      if (isBytes && !field->has_default_value()) {
+        return "com.google.protobuf.ByteString.EMPTY";
+      }
+
+      // Escaping strings correctly for Java and generating efficient
+      // initializers for ByteStrings are both tricky.  We can sidestep the
+      // whole problem by just grabbing the default value from the descriptor.
+      return strings::Substitute(
+        "(($0) $1.getDescriptor().getFields().get($2).getDefaultValue())",
+        isBytes ? "com.google.protobuf.ByteString" : "java.lang.String",
+        ClassName(field->containing_type()), field->index());
+    }
+
+    case FieldDescriptor::CPPTYPE_ENUM:
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      GOOGLE_LOG(FATAL) << "Can't get here.";
+      return "";
+
+    // No default because we want the compiler to complain if any new
+    // types are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return "";
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+                           map<string, string>* variables) {
+  (*variables)["name"] =
+    UnderscoresToCamelCase(descriptor);
+  (*variables)["capitalized_name"] =
+    UnderscoresToCapitalizedCamelCase(descriptor);
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
+  (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
+  (*variables)["default"] = DefaultValue(descriptor);
+  (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
+}
+
+}  // namespace
+
+// ===================================================================
+
+PrimitiveFieldGenerator::
+PrimitiveFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, &variables_);
+}
+
+PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+
+void PrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private boolean has$capitalized_name$;\n"
+    "private $type$ $name$_ = $default$;\n"
+    "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
+    "public $type$ get$capitalized_name$() { return $name$_; }\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "public boolean has$capitalized_name$() {\n"
+    "  return result.has$capitalized_name$();\n"
+    "}\n"
+    "public $type$ get$capitalized_name$() {\n"
+    "  return result.get$capitalized_name$();\n"
+    "}\n"
+    "public Builder set$capitalized_name$($type$ value) {\n"
+    "  result.has$capitalized_name$ = true;\n"
+    "  result.$name$_ = value;\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder clear$capitalized_name$() {\n"
+    "  result.has$capitalized_name$ = false;\n"
+    "  result.$name$_ = $default$;\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (other.has$capitalized_name$()) {\n"
+    "  set$capitalized_name$(other.get$capitalized_name$());\n"
+    "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  // Nothing to do here for primitive types.
+}
+
+void PrimitiveFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "set$capitalized_name$(input.read$capitalized_type$());\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (has$capitalized_name$()) {\n"
+    "  output.write$capitalized_type$($number$, get$capitalized_name$());\n"
+    "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (has$capitalized_name$()) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .compute$capitalized_type$Size($number$, get$capitalized_name$());\n"
+    "}\n");
+}
+
+string PrimitiveFieldGenerator::GetBoxedType() const {
+  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+// ===================================================================
+
+RepeatedPrimitiveFieldGenerator::
+RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor)
+  : descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, &variables_);
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private java.util.List<$boxed_type$> $name$_ =\n"
+    "  java.util.Collections.emptyList();\n"
+    "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n"
+    "  return $name$_;\n"   // note:  unmodifiable list
+    "}\n"
+    "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
+    "public $type$ get$capitalized_name$(int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    // Note:  We return an unmodifiable list because otherwise the caller
+    //   could hold on to the returned list and modify it after the message
+    //   has been built, thus mutating the message which is supposed to be
+    //   immutable.
+    "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n"
+    "  return java.util.Collections.unmodifiableList(result.$name$_);\n"
+    "}\n"
+    "public int get$capitalized_name$Count() {\n"
+    "  return result.get$capitalized_name$Count();\n"
+    "}\n"
+    "public $type$ get$capitalized_name$(int index) {\n"
+    "  return result.get$capitalized_name$(index);\n"
+    "}\n"
+    "public Builder set$capitalized_name$(int index, $type$ value) {\n"
+    "  result.$name$_.set(index, value);\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder add$capitalized_name$($type$ value) {\n"
+    "  if (result.$name$_.isEmpty()) {\n"
+    "    result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+    "  }\n"
+    "  result.$name$_.add(value);\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder addAll$capitalized_name$(\n"
+    "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
+    "  if (result.$name$_.isEmpty()) {\n"
+    "    result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+    "  }\n"
+    "  super.addAll(values, result.$name$_);\n"
+    "  return this;\n"
+    "}\n"
+    "public Builder clear$capitalized_name$() {\n"
+    "  result.$name$_ = java.util.Collections.emptyList();\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!other.$name$_.isEmpty()) {\n"
+    "  if (result.$name$_.isEmpty()) {\n"
+    "    result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+    "  }\n"
+    "  result.$name$_.addAll(other.$name$_);\n"
+    "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
+    "  result.$name$_ =\n"
+    "    java.util.Collections.unmodifiableList(result.$name$_);\n"
+    "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "add$capitalized_name$(input.read$capitalized_type$());\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for ($type$ element : get$capitalized_name$List()) {\n"
+    "  output.write$capitalized_type$($number$, element);\n"
+    "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for ($type$ element : get$capitalized_name$List()) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .compute$capitalized_type$Size($number$, element);\n"
+    "}\n");
+}
+
+string RepeatedPrimitiveFieldGenerator::GetBoxedType() const {
+  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.h b/src/google/protobuf/compiler/java/java_primitive_field.h
new file mode 100644
index 0000000..6fe9177
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_primitive_field.h
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class PrimitiveFieldGenerator : public FieldGenerator {
+ public:
+  explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+  ~PrimitiveFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
+};
+
+class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+  ~RepeatedPrimitiveFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc
new file mode 100644
index 0000000..8cb0627
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_service.cc
@@ -0,0 +1,225 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_service.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor)
+  : descriptor_(descriptor) {}
+
+ServiceGenerator::~ServiceGenerator() {}
+
+void ServiceGenerator::Generate(io::Printer* printer) {
+  bool is_own_file = descriptor_->file()->options().java_multiple_files();
+  printer->Print(
+    "public $static$ abstract class $classname$\n"
+    "    implements com.google.protobuf.Service {\n",
+    "static", is_own_file ? "" : "static",
+    "classname", descriptor_->name());
+  printer->Indent();
+
+  // Generate abstract method declarations.
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    map<string, string> vars;
+    vars["name"] = UnderscoresToCamelCase(method);
+    vars["input"] = ClassName(method->input_type());
+    vars["output"] = ClassName(method->output_type());
+    printer->Print(vars,
+      "public abstract void $name$(\n"
+      "    com.google.protobuf.RpcController controller,\n"
+      "    $input$ request,\n"
+      "    com.google.protobuf.RpcCallback<$output$> done);\n");
+  }
+
+  // Generate getDescriptor() and getDescriptorForType().
+  printer->Print(
+    "\n"
+    "public static final\n"
+    "    com.google.protobuf.Descriptors.ServiceDescriptor\n"
+    "    getDescriptor() {\n"
+    "  return $file$.getDescriptor().getServices().get($index$);\n"
+    "}\n"
+    "public final com.google.protobuf.Descriptors.ServiceDescriptor\n"
+    "    getDescriptorForType() {\n"
+    "  return getDescriptor();\n"
+    "}\n",
+    "file", ClassName(descriptor_->file()),
+    "index", SimpleItoa(descriptor_->index()));
+
+  // Generate more stuff.
+  GenerateCallMethod(printer);
+  GenerateGetPrototype(REQUEST, printer);
+  GenerateGetPrototype(RESPONSE, printer);
+  GenerateStub(printer);
+
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
+  printer->Print(
+    "\n"
+    "public final void callMethod(\n"
+    "    com.google.protobuf.Descriptors.MethodDescriptor method,\n"
+    "    com.google.protobuf.RpcController controller,\n"
+    "    com.google.protobuf.Message request,\n"
+    "    com.google.protobuf.RpcCallback<\n"
+    "      com.google.protobuf.Message> done) {\n"
+    "  if (method.getService() != getDescriptor()) {\n"
+    "    throw new java.lang.IllegalArgumentException(\n"
+    "      \"Service.callMethod() given method descriptor for wrong \" +\n"
+    "      \"service type.\");\n"
+    "  }\n"
+    "  switch(method.getIndex()) {\n");
+  printer->Indent();
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    map<string, string> vars;
+    vars["index"] = SimpleItoa(i);
+    vars["method"] = UnderscoresToCamelCase(method);
+    vars["input"] = ClassName(method->input_type());
+    vars["output"] = ClassName(method->output_type());
+    printer->Print(vars,
+      "case $index$:\n"
+      "  this.$method$(controller, ($input$)request,\n"
+      "    com.google.protobuf.RpcUtil.<$output$>specializeCallback(\n"
+      "      done));\n"
+      "  return;\n");
+  }
+
+  printer->Print(
+    "default:\n"
+    "  throw new java.lang.RuntimeException(\"Can't get here.\");\n");
+
+  printer->Outdent();
+  printer->Outdent();
+
+  printer->Print(
+    "  }\n"
+    "}\n"
+    "\n");
+}
+
+void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
+                                            io::Printer* printer) {
+  printer->Print(
+    "public final com.google.protobuf.Message\n"
+    "    get$request_or_response$Prototype(\n"
+    "    com.google.protobuf.Descriptors.MethodDescriptor method) {\n"
+    "  if (method.getService() != getDescriptor()) {\n"
+    "    throw new java.lang.IllegalArgumentException(\n"
+    "      \"Service.get$request_or_response$Prototype() given method \" +\n"
+    "      \"descriptor for wrong service type.\");\n"
+    "  }\n"
+    "  switch(method.getIndex()) {\n",
+    "request_or_response", (which == REQUEST) ? "Request" : "Response");
+  printer->Indent();
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    map<string, string> vars;
+    vars["index"] = SimpleItoa(i);
+    vars["type"] = ClassName(
+      (which == REQUEST) ? method->input_type() : method->output_type());
+    printer->Print(vars,
+      "case $index$:\n"
+      "  return $type$.getDefaultInstance();\n");
+  }
+
+  printer->Print(
+    "default:\n"
+    "  throw new java.lang.RuntimeException(\"Can't get here.\");\n");
+
+  printer->Outdent();
+  printer->Outdent();
+
+  printer->Print(
+    "  }\n"
+    "}\n"
+    "\n");
+}
+
+void ServiceGenerator::GenerateStub(io::Printer* printer) {
+  printer->Print(
+    "public static Stub newStub(\n"
+    "    com.google.protobuf.RpcChannel channel) {\n"
+    "  return new Stub(channel);\n"
+    "}\n"
+    "\n"
+    "public static final class Stub extends $classname$ {\n",
+    "classname", ClassName(descriptor_));
+  printer->Indent();
+
+  printer->Print(
+    "private Stub(com.google.protobuf.RpcChannel channel) {\n"
+    "  this.channel = channel;\n"
+    "}\n"
+    "\n"
+    "private final com.google.protobuf.RpcChannel channel;\n"
+    "\n"
+    "public com.google.protobuf.RpcChannel getChannel() {\n"
+    "  return channel;\n"
+    "}\n");
+
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    map<string, string> vars;
+    vars["index"] = SimpleItoa(i);
+    vars["method"] = UnderscoresToCamelCase(method);
+    vars["input"] = ClassName(method->input_type());
+    vars["output"] = ClassName(method->output_type());
+    printer->Print(vars,
+      "\n"
+      "public void $method$(\n"
+      "    com.google.protobuf.RpcController controller,\n"
+      "    $input$ request,\n"
+      "    com.google.protobuf.RpcCallback<$output$> done) {\n"
+      "  channel.callMethod(\n"
+      "    getDescriptor().getMethods().get($index$),\n"
+      "    controller,\n"
+      "    request,\n"
+      "    $output$.getDefaultInstance(),\n"
+      "    com.google.protobuf.RpcUtil.generalizeCallback(\n"
+      "      done,\n"
+      "      $output$.class,\n"
+      "      $output$.getDefaultInstance()));\n"
+      "}\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_service.h b/src/google/protobuf/compiler/java/java_service.h
new file mode 100644
index 0000000..adf3dfd
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_service.h
@@ -0,0 +1,66 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__
+
+#include <map>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ServiceGenerator {
+ public:
+  explicit ServiceGenerator(const ServiceDescriptor* descriptor);
+  ~ServiceGenerator();
+
+  void Generate(io::Printer* printer);
+
+ private:
+  // Generate the implementation of Service.callMethod().
+  void GenerateCallMethod(io::Printer* printer);
+
+  // Generate the implementations of Service.get{Request,Response}Prototype().
+  enum RequestOrResponse { REQUEST, RESPONSE };
+  void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer);
+
+  // Generate a stub implementation of the service.
+  void GenerateStub(io::Printer* printer);
+
+  const ServiceDescriptor* descriptor_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+#endif  // NET_PROTO2_COMPILER_JAVA_SERVICE_H__
+}  // namespace google
diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc
new file mode 100644
index 0000000..a5a2834
--- /dev/null
+++ b/src/google/protobuf/compiler/main.cc
@@ -0,0 +1,46 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/compiler/cpp/cpp_generator.h>
+#include <google/protobuf/compiler/python/python_generator.h>
+#include <google/protobuf/compiler/java/java_generator.h>
+
+
+int main(int argc, char* argv[]) {
+
+  google::protobuf::compiler::CommandLineInterface cli;
+
+  // Proto2 C++
+  google::protobuf::compiler::cpp::CppGenerator cpp_generator;
+  cli.RegisterGenerator("--cpp_out", &cpp_generator,
+                        "Generate C++ header and source.");
+
+  // Proto2 Java
+  google::protobuf::compiler::java::JavaGenerator java_generator;
+  cli.RegisterGenerator("--java_out", &java_generator,
+                        "Generate Java source file.");
+
+
+  // Proto2 Python
+  google::protobuf::compiler::python::Generator py_generator;
+  cli.RegisterGenerator("--python_out", &py_generator,
+                        "Generate Python source file.");
+
+  return cli.Run(argc, argv);
+}
diff --git a/src/google/protobuf/compiler/package_info.h b/src/google/protobuf/compiler/package_info.h
new file mode 100644
index 0000000..aa0c282
--- /dev/null
+++ b/src/google/protobuf/compiler/package_info.h
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file exists solely to document the google::protobuf::compiler namespace.
+// It is not compiled into anything, but it may be read by an automated
+// documentation generator.
+
+namespace google {
+
+namespace protobuf {
+
+// Implementation of the Protocol Buffer compiler.
+//
+// This package contains code for parsing .proto files and generating code
+// based on them.  There are two reasons you might be interested in this
+// package:
+// - You want to parse .proto files at runtime.  In this case, you should
+//   look at importer.h.  Since this functionality is widely useful, it is
+//   included in the libprotobuf base library; you do not have to link against
+//   libprotoc.
+// - You want to write a custom protocol compiler which generates different
+//   kinds of code, e.g. code in a different language which is not supported
+//   by the official compiler.  For this purpose, command_line_interface.h
+//   provides you with a complete compiler front-end, so all you need to do
+//   is write a custom implementation of CodeGenerator and a trivial main()
+//   function.  You can even make your compiler support the official languages
+//   in addition to your own.  Since this functionality is only useful to those
+//   writing custom compilers, it is in a separate library called "libprotoc"
+//   which you will have to link against.
+namespace compiler {}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
new file mode 100644
index 0000000..622895f
--- /dev/null
+++ b/src/google/protobuf/compiler/parser.cc
@@ -0,0 +1,1105 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Recursive descent FTW.
+
+#include <google/protobuf/stubs/hash.h>
+#include <float.h>
+
+
+#include <google/protobuf/compiler/parser.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map-util.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+using internal::WireFormat;
+
+namespace {
+
+typedef hash_map<string, FieldDescriptorProto::Type> TypeNameMap;
+
+TypeNameMap MakeTypeNameTable() {
+  TypeNameMap result;
+
+  result["double"  ] = FieldDescriptorProto::TYPE_DOUBLE;
+  result["float"   ] = FieldDescriptorProto::TYPE_FLOAT;
+  result["uint64"  ] = FieldDescriptorProto::TYPE_UINT64;
+  result["fixed64" ] = FieldDescriptorProto::TYPE_FIXED64;
+  result["fixed32" ] = FieldDescriptorProto::TYPE_FIXED32;
+  result["bool"    ] = FieldDescriptorProto::TYPE_BOOL;
+  result["string"  ] = FieldDescriptorProto::TYPE_STRING;
+  result["group"   ] = FieldDescriptorProto::TYPE_GROUP;
+
+  result["bytes"   ] = FieldDescriptorProto::TYPE_BYTES;
+  result["uint32"  ] = FieldDescriptorProto::TYPE_UINT32;
+  result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32;
+  result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64;
+  result["int32"   ] = FieldDescriptorProto::TYPE_INT32;
+  result["int64"   ] = FieldDescriptorProto::TYPE_INT64;
+  result["sint32"  ] = FieldDescriptorProto::TYPE_SINT32;
+  result["sint64"  ] = FieldDescriptorProto::TYPE_SINT64;
+
+  return result;
+}
+
+const TypeNameMap kTypeNames = MakeTypeNameTable();
+
+}  // anonymous namespace
+
+// Makes code slightly more readable.  The meaning of "DO(foo)" is
+// "Execute foo and fail if it fails.", where failure is indicated by
+// returning false.
+#define DO(STATEMENT) if (STATEMENT) {} else return false
+
+// ===================================================================
+
+Parser::Parser()
+  : input_(NULL),
+    error_collector_(NULL),
+    source_location_table_(NULL),
+    had_errors_(false),
+    require_syntax_identifier_(false) {
+}
+
+Parser::~Parser() {
+}
+
+// ===================================================================
+
+inline bool Parser::LookingAt(const char* text) {
+  return input_->current().text == text;
+}
+
+inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) {
+  return input_->current().type == token_type;
+}
+
+inline bool Parser::AtEnd() {
+  return LookingAtType(io::Tokenizer::TYPE_END);
+}
+
+bool Parser::TryConsume(const char* text) {
+  if (LookingAt(text)) {
+    input_->Next();
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool Parser::Consume(const char* text, const char* error) {
+  if (TryConsume(text)) {
+    return true;
+  } else {
+    AddError(error);
+    return false;
+  }
+}
+
+bool Parser::Consume(const char* text) {
+  if (TryConsume(text)) {
+    return true;
+  } else {
+    AddError("Expected \"" + string(text) + "\".");
+    return false;
+  }
+}
+
+bool Parser::ConsumeIdentifier(string* output, const char* error) {
+  if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+    *output = input_->current().text;
+    input_->Next();
+    return true;
+  } else {
+    AddError(error);
+    return false;
+  }
+}
+
+bool Parser::ConsumeInteger(int* output, const char* error) {
+  if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+    uint64 value = 0;
+    if (!io::Tokenizer::ParseInteger(input_->current().text,
+                                     kint32max, &value)) {
+      AddError("Integer out of range.");
+      // We still return true because we did, in fact, parse an integer.
+    }
+    *output = value;
+    input_->Next();
+    return true;
+  } else {
+    AddError(error);
+    return false;
+  }
+}
+
+bool Parser::ConsumeInteger64(uint64 max_value, uint64* output,
+                              const char* error) {
+  if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+    if (!io::Tokenizer::ParseInteger(input_->current().text, max_value,
+                                     output)) {
+      AddError("Integer out of range.");
+      // We still return true because we did, in fact, parse an integer.
+      *output = 0;
+    }
+    input_->Next();
+    return true;
+  } else {
+    AddError(error);
+    return false;
+  }
+}
+
+bool Parser::ConsumeNumber(double* output, const char* error) {
+  if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
+    *output = io::Tokenizer::ParseFloat(input_->current().text);
+    input_->Next();
+    return true;
+  } else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+    // Also accept integers.
+    uint64 value = 0;
+    if (!io::Tokenizer::ParseInteger(input_->current().text,
+                                     kuint64max, &value)) {
+      AddError("Integer out of range.");
+      // We still return true because we did, in fact, parse a number.
+    }
+    *output = value;
+    input_->Next();
+    return true;
+  } else {
+    AddError(error);
+    return false;
+  }
+}
+
+bool Parser::ConsumeString(string* output, const char* error) {
+  if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+    io::Tokenizer::ParseString(input_->current().text, output);
+    input_->Next();
+    return true;
+  } else {
+    AddError(error);
+    return false;
+  }
+}
+
+// -------------------------------------------------------------------
+
+void Parser::AddError(int line, int column, const string& error) {
+  if (error_collector_ != NULL) {
+    error_collector_->AddError(line, column, error);
+  }
+  had_errors_ = true;
+}
+
+void Parser::AddError(const string& error) {
+  AddError(input_->current().line, input_->current().column, error);
+}
+
+void Parser::RecordLocation(
+    const Message* descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location,
+    int line, int column) {
+  if (source_location_table_ != NULL) {
+    source_location_table_->Add(descriptor, location, line, column);
+  }
+}
+
+void Parser::RecordLocation(
+    const Message* descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location) {
+  RecordLocation(descriptor, location,
+                 input_->current().line, input_->current().column);
+}
+
+// -------------------------------------------------------------------
+
+void Parser::SkipStatement() {
+  while (true) {
+    if (AtEnd()) {
+      return;
+    } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
+      if (TryConsume(";")) {
+        return;
+      } else if (TryConsume("{")) {
+        SkipRestOfBlock();
+        return;
+      } else if (LookingAt("}")) {
+        return;
+      }
+    }
+    input_->Next();
+  }
+}
+
+void Parser::SkipRestOfBlock() {
+  while (true) {
+    if (AtEnd()) {
+      return;
+    } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
+      if (TryConsume("}")) {
+        return;
+      } else if (TryConsume("{")) {
+        SkipRestOfBlock();
+      }
+    }
+    input_->Next();
+  }
+}
+
+// ===================================================================
+
+bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
+  input_ = input;
+  had_errors_ = false;
+  syntax_identifier_.clear();
+
+  if (LookingAtType(io::Tokenizer::TYPE_START)) {
+    // Advance to first token.
+    input_->Next();
+  }
+
+  if (require_syntax_identifier_ || LookingAt("syntax")) {
+    if (!ParseSyntaxIdentifier()) {
+      // Don't attempt to parse the file if we didn't recognize the syntax
+      // identifier.
+      return false;
+    }
+  } else {
+    syntax_identifier_ = "proto2";
+  }
+
+  // Repeatedly parse statemetns until we reach the end of the file.
+  while (!AtEnd()) {
+    if (!ParseTopLevelStatement(file)) {
+      // This statement failed to parse.  Skip it, but keep looping to parse
+      // other statements.
+      SkipStatement();
+
+      if (LookingAt("}")) {
+        AddError("Unmatched \"}\".");
+        input_->Next();
+      }
+    }
+  }
+
+  input_ = NULL;
+  return !had_errors_;
+}
+
+bool Parser::ParseSyntaxIdentifier() {
+  DO(Consume("syntax", "File must begin with 'syntax = \"proto2\";'."));
+  DO(Consume("="));
+  io::Tokenizer::Token syntax_token = input_->current();
+  string syntax;
+  DO(ConsumeString(&syntax, "Expected syntax identifier."));
+  DO(Consume(";"));
+
+  syntax_identifier_ = syntax;
+
+  if (syntax != "proto2") {
+    AddError(syntax_token.line, syntax_token.column,
+      "Unrecognized syntax identifier \"" + syntax + "\".  This parser "
+      "only recognizes \"proto2\".");
+    return false;
+  }
+
+  return true;
+}
+
+bool Parser::ParseTopLevelStatement(FileDescriptorProto* file) {
+  if (TryConsume(";")) {
+    // empty statement; ignore
+    return true;
+  } else if (LookingAt("message")) {
+    return ParseMessageDefinition(file->add_message_type());
+  } else if (LookingAt("enum")) {
+    return ParseEnumDefinition(file->add_enum_type());
+  } else if (LookingAt("service")) {
+    return ParseServiceDefinition(file->add_service());
+  } else if (LookingAt("extend")) {
+    return ParseExtend(file->mutable_extension(),
+                       file->mutable_message_type());
+  } else if (LookingAt("import")) {
+    return ParseImport(file->add_dependency());
+  } else if (LookingAt("package")) {
+    return ParsePackage(file);
+  } else if (LookingAt("option")) {
+    return ParseOption(file->mutable_options());
+  } else {
+    AddError("Expected top-level statement (e.g. \"message\").");
+    return false;
+  }
+}
+
+// -------------------------------------------------------------------
+// Messages
+
+bool Parser::ParseMessageDefinition(DescriptorProto* message) {
+  DO(Consume("message"));
+  RecordLocation(message, DescriptorPool::ErrorCollector::NAME);
+  DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
+  DO(ParseMessageBlock(message));
+  return true;
+}
+
+bool Parser::ParseMessageBlock(DescriptorProto* message) {
+  DO(Consume("{"));
+
+  while (!TryConsume("}")) {
+    if (AtEnd()) {
+      AddError("Reached end of input in message definition (missing '}').");
+      return false;
+    }
+
+    if (!ParseMessageStatement(message)) {
+      // This statement failed to parse.  Skip it, but keep looping to parse
+      // other statements.
+      SkipStatement();
+    }
+  }
+
+  return true;
+}
+
+bool Parser::ParseMessageStatement(DescriptorProto* message) {
+  if (TryConsume(";")) {
+    // empty statement; ignore
+    return true;
+  } else if (LookingAt("message")) {
+    return ParseMessageDefinition(message->add_nested_type());
+  } else if (LookingAt("enum")) {
+    return ParseEnumDefinition(message->add_enum_type());
+  } else if (LookingAt("extensions")) {
+    return ParseExtensions(message);
+  } else if (LookingAt("extend")) {
+    return ParseExtend(message->mutable_extension(),
+                       message->mutable_nested_type());
+  } else if (LookingAt("option")) {
+    return ParseOption(message->mutable_options());
+  } else {
+    return ParseMessageField(message->add_field(),
+                             message->mutable_nested_type());
+  }
+}
+
+bool Parser::ParseMessageField(FieldDescriptorProto* field,
+                               RepeatedPtrField<DescriptorProto>* messages) {
+  // Parse label and type.
+  FieldDescriptorProto::Label label;
+  DO(ParseLabel(&label));
+  field->set_label(label);
+
+  RecordLocation(field, DescriptorPool::ErrorCollector::TYPE);
+  FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
+  string type_name;
+  DO(ParseType(&type, &type_name));
+  if (type_name.empty()) {
+    field->set_type(type);
+  } else {
+    field->set_type_name(type_name);
+  }
+
+  // Parse name and '='.
+  RecordLocation(field, DescriptorPool::ErrorCollector::NAME);
+  io::Tokenizer::Token name_token = input_->current();
+  DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
+  DO(Consume("=", "Missing field number."));
+
+  // Parse field number.
+  RecordLocation(field, DescriptorPool::ErrorCollector::NUMBER);
+  int number;
+  DO(ConsumeInteger(&number, "Expected field number."));
+  field->set_number(number);
+
+  // Parse options.
+  DO(ParseFieldOptions(field));
+
+  // Deal with groups.
+  if (type_name.empty() && type == FieldDescriptorProto::TYPE_GROUP) {
+    DescriptorProto* group = messages->Add();
+    group->set_name(field->name());
+    // Record name location to match the field name's location.
+    RecordLocation(group, DescriptorPool::ErrorCollector::NAME,
+                   name_token.line, name_token.column);
+
+    // As a hack for backwards-compatibility, we force the group name to start
+    // with a capital letter and lower-case the field name.  New code should
+    // not use groups; it should use nested messages.
+    if (group->name()[0] < 'A' || 'Z' < group->name()[0]) {
+      AddError(name_token.line, name_token.column,
+        "Group names must start with a capital letter.");
+    }
+    LowerString(field->mutable_name());
+
+    field->set_type_name(group->name());
+    if (LookingAt("{")) {
+      DO(ParseMessageBlock(group));
+    } else {
+      AddError("Missing group body.");
+      return false;
+    }
+  } else {
+    DO(Consume(";"));
+  }
+
+  return true;
+}
+
+bool Parser::ParseFieldOptions(FieldDescriptorProto* field) {
+  if (!TryConsume("[")) return true;
+
+  // Parse field options.
+  do {
+    if (LookingAt("default")) {
+      DO(ParseDefaultAssignment(field));
+    } else {
+      DO(ParseOptionAssignment(field->mutable_options()));
+    }
+  } while (TryConsume(","));
+
+  DO(Consume("]"));
+  return true;
+}
+
+bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
+  if (field->has_default_value()) {
+    AddError("Already set option \"default\".");
+    field->clear_default_value();
+  }
+
+  DO(Consume("default"));
+  DO(Consume("="));
+
+  RecordLocation(field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
+  string* default_value = field->mutable_default_value();
+
+  if (!field->has_type()) {
+    // The field has a type name, but we don't know if it is a message or an
+    // enum yet.  Assume an enum for now.
+    DO(ConsumeIdentifier(default_value, "Expected identifier."));
+    return true;
+  }
+
+  switch (field->type()) {
+    case FieldDescriptorProto::TYPE_INT32:
+    case FieldDescriptorProto::TYPE_INT64:
+    case FieldDescriptorProto::TYPE_SINT32:
+    case FieldDescriptorProto::TYPE_SINT64:
+    case FieldDescriptorProto::TYPE_SFIXED32:
+    case FieldDescriptorProto::TYPE_SFIXED64: {
+      uint64 max_value = kint64max;
+      if (field->type() == FieldDescriptorProto::TYPE_INT32 ||
+          field->type() == FieldDescriptorProto::TYPE_SINT32 ||
+          field->type() == FieldDescriptorProto::TYPE_SFIXED32) {
+        max_value = kint32max;
+      }
+
+      // These types can be negative.
+      if (TryConsume("-")) {
+        default_value->append("-");
+        // Two's complement always has one more negative value than positive.
+        ++max_value;
+      }
+      // Parse the integer to verify that it is not out-of-range.
+      uint64 value;
+      DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+      // And stringify it again.
+      default_value->append(SimpleItoa(value));
+      break;
+    }
+
+    case FieldDescriptorProto::TYPE_UINT32:
+    case FieldDescriptorProto::TYPE_UINT64:
+    case FieldDescriptorProto::TYPE_FIXED32:
+    case FieldDescriptorProto::TYPE_FIXED64: {
+      uint64 max_value = kuint64max;
+      if (field->type() == FieldDescriptorProto::TYPE_UINT32 ||
+          field->type() == FieldDescriptorProto::TYPE_FIXED32) {
+        max_value = kuint32max;
+      }
+
+      // Numeric, not negative.
+      if (TryConsume("-")) {
+        AddError("Unsigned field can't have negative default value.");
+      }
+      // Parse the integer to verify that it is not out-of-range.
+      uint64 value;
+      DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+      // And stringify it again.
+      default_value->append(SimpleItoa(value));
+      break;
+    }
+
+    case FieldDescriptorProto::TYPE_FLOAT:
+    case FieldDescriptorProto::TYPE_DOUBLE:
+      // These types can be negative.
+      if (TryConsume("-")) {
+        default_value->append("-");
+      }
+      // Parse the integer because we have to convert hex integers to decimal
+      // floats.
+      double value;
+      DO(ConsumeNumber(&value, "Expected number."));
+      // And stringify it again.
+      default_value->append(SimpleDtoa(value));
+      break;
+
+    case FieldDescriptorProto::TYPE_BOOL:
+      if (TryConsume("true")) {
+        default_value->assign("true");
+      } else if (TryConsume("false")) {
+        default_value->assign("false");
+      } else {
+        AddError("Expected \"true\" or \"false\".");
+        return false;
+      }
+      break;
+
+    case FieldDescriptorProto::TYPE_STRING:
+      DO(ConsumeString(default_value, "Expected string."));
+      break;
+
+    case FieldDescriptorProto::TYPE_BYTES:
+      DO(ConsumeString(default_value, "Expected string."));
+      *default_value = CEscape(*default_value);
+      break;
+
+    case FieldDescriptorProto::TYPE_ENUM:
+      DO(ConsumeIdentifier(default_value, "Expected identifier."));
+      break;
+
+    case FieldDescriptorProto::TYPE_MESSAGE:
+    case FieldDescriptorProto::TYPE_GROUP:
+      AddError("Messages can't have default values.");
+      return false;
+  }
+
+  return true;
+}
+
+bool Parser::ParseOptionAssignment(Message* options) {
+  Message::Reflection* reflection = options->GetReflection();
+  const Descriptor* descriptor = options->GetDescriptor();
+
+  // Parse name.
+  string name;
+  int line = input_->current().line;
+  int column = input_->current().column;
+  DO(ConsumeIdentifier(&name, "Expected option name."));
+
+  // Is it valid?
+  const FieldDescriptor* field = descriptor->FindFieldByName(name);
+  if (field == NULL) {
+    AddError(line, column, "Unknown option: " + name);
+    return false;
+  }
+  if (field->is_repeated()) {
+    AddError(line, column, "Not implemented: repeated options.");
+    return false;
+  }
+  if (reflection->HasField(field)) {
+    AddError(line, column, "Option \"" + name + "\" was already set.");
+    return false;
+  }
+
+  // Are we trying to assign a member of a message?
+  if (LookingAt(".")) {
+    if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+      AddError("Option \"" + name + "\" is an atomic type, not a message.");
+      return false;
+    }
+    DO(Consume("."));
+
+    // This field is a message/group.  The user must identify a field within
+    // it to set.
+    return ParseOptionAssignment(reflection->MutableMessage(field));
+  }
+
+  DO(Consume("="));
+
+  // Parse the option value.
+  switch (field->cpp_type()) {
+    case FieldDescriptor::CPPTYPE_INT32: {
+      uint64 value;
+      bool is_negative = TryConsume("-");
+      uint64 max_value = kint32max;
+      if (is_negative) ++max_value;
+      DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+      reflection->SetInt32(field, is_negative ? -value : value);
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_INT64: {
+      uint64 value;
+      bool is_negative = TryConsume("-");
+      uint64 max_value = kint64max;
+      if (is_negative) ++max_value;
+      DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+      reflection->SetInt64(field, is_negative ? -value : value);
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_UINT32: {
+      uint64 value;
+      DO(ConsumeInteger64(kuint32max, &value, "Expected integer."));
+      reflection->SetUInt32(field, value);
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_UINT64: {
+      uint64 value;
+      DO(ConsumeInteger64(kuint64max, &value, "Expected integer."));
+      reflection->SetUInt64(field, value);
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_DOUBLE: {
+      double value;
+      bool is_negative = TryConsume("-");
+      DO(ConsumeNumber(&value, "Expected number."));
+      reflection->SetDouble(field, is_negative ? -value : value);
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_FLOAT: {
+      double value;
+      bool is_negative = TryConsume("-");
+      DO(ConsumeNumber(&value, "Expected number."));
+      reflection->SetFloat(field, is_negative ? -value : value);
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_BOOL:
+      if (TryConsume("true")) {
+        reflection->SetBool(field, true);
+      } else if (TryConsume("false")) {
+        reflection->SetBool(field, false);
+      } else {
+        AddError("Expected \"true\" or \"false\".");
+        return false;
+      }
+      break;
+
+    case FieldDescriptor::CPPTYPE_ENUM: {
+      string value_name;
+      int value_line = input_->current().line;
+      int value_column = input_->current().column;
+      DO(ConsumeIdentifier(&value_name, "Expected enum value."));
+      const EnumValueDescriptor* value =
+        field->enum_type()->FindValueByName(value_name);
+      if (value == NULL) {
+        AddError(value_line, value_column,
+          "Enum type \"" + field->enum_type()->full_name() + "\" has no value "
+          "named \"" + value_name + "\".");
+        return false;
+      }
+      reflection->SetEnum(field, value);
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_STRING: {
+      string value;
+      DO(ConsumeString(&value, "Expected string."));
+      reflection->SetString(field, value);
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_MESSAGE: {
+      // TODO(kenton):  Allow use of protocol buffer text format here?
+      AddError("\"" + name + "\" is a message.  To set fields within it, use "
+               "syntax like \"" + name + ".foo = value\".");
+      return false;
+      break;
+    }
+  }
+
+  return true;
+}
+
+bool Parser::ParseExtensions(DescriptorProto* message) {
+  // Parse the declaration.
+  DO(Consume("extensions"));
+
+  do {
+    DescriptorProto::ExtensionRange* range = message->add_extension_range();
+    RecordLocation(range, DescriptorPool::ErrorCollector::NUMBER);
+
+    int start, end;
+    DO(ConsumeInteger(&start, "Expected field number range."));
+
+    if (TryConsume("to")) {
+      if (TryConsume("max")) {
+        end = FieldDescriptor::kMaxNumber;
+      } else {
+        DO(ConsumeInteger(&end, "Expected integer."));
+      }
+    } else {
+      end = start;
+    }
+
+    // Users like to specify inclusive ranges, but in code we like the end
+    // number to be exclusive.
+    ++end;
+
+    range->set_start(start);
+    range->set_end(end);
+  } while (TryConsume(","));
+
+  DO(Consume(";"));
+  return true;
+}
+
+bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
+                         RepeatedPtrField<DescriptorProto>* messages) {
+  DO(Consume("extend"));
+
+  // We expect to see at least one extension field defined in the extend block.
+  // We need to create it now so we can record the extendee's location.
+  FieldDescriptorProto* first_field = extensions->Add();
+
+  // Parse the extendee type.
+  RecordLocation(first_field, DescriptorPool::ErrorCollector::EXTENDEE);
+  DO(ParseUserDefinedType(first_field->mutable_extendee()));
+
+  // Parse the block.
+  DO(Consume("{"));
+
+  bool is_first = true;
+
+  do {
+    if (AtEnd()) {
+      AddError("Reached end of input in extend definition (missing '}').");
+      return false;
+    }
+
+    FieldDescriptorProto* field;
+    if (is_first) {
+      field = first_field;
+      is_first = false;
+    } else {
+      field = extensions->Add();
+      field->set_extendee(first_field->extendee());
+    }
+
+    if (!ParseMessageField(field, messages)) {
+      // This statement failed to parse.  Skip it, but keep looping to parse
+      // other statements.
+      SkipStatement();
+    }
+  } while(!TryConsume("}"));
+
+  return true;
+}
+
+// -------------------------------------------------------------------
+// Enums
+
+bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type) {
+  DO(Consume("enum"));
+  RecordLocation(enum_type, DescriptorPool::ErrorCollector::NAME);
+  DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
+  DO(ParseEnumBlock(enum_type));
+  return true;
+}
+
+bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) {
+  DO(Consume("{"));
+
+  while (!TryConsume("}")) {
+    if (AtEnd()) {
+      AddError("Reached end of input in enum definition (missing '}').");
+      return false;
+    }
+
+    if (!ParseEnumStatement(enum_type)) {
+      // This statement failed to parse.  Skip it, but keep looping to parse
+      // other statements.
+      SkipStatement();
+    }
+  }
+
+  return true;
+}
+
+bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type) {
+  if (TryConsume(";")) {
+    // empty statement; ignore
+    return true;
+  } else if (LookingAt("option")) {
+    return ParseOption(enum_type->mutable_options());
+  } else {
+    return ParseEnumConstant(enum_type->add_value());
+  }
+}
+
+bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value) {
+  RecordLocation(enum_value, DescriptorPool::ErrorCollector::NAME);
+  DO(ConsumeIdentifier(enum_value->mutable_name(),
+                       "Expected enum constant name."));
+  DO(Consume("=", "Missing numeric value for enum constant."));
+
+  bool is_negative = TryConsume("-");
+  int number;
+  DO(ConsumeInteger(&number, "Expected integer."));
+  if (is_negative) number *= -1;
+  enum_value->set_number(number);
+
+  // TODO(kenton):  Options for enum values?
+
+  DO(Consume(";"));
+
+  return true;
+}
+
+// -------------------------------------------------------------------
+// Services
+
+bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service) {
+  DO(Consume("service"));
+  RecordLocation(service, DescriptorPool::ErrorCollector::NAME);
+  DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
+  DO(ParseServiceBlock(service));
+  return true;
+}
+
+bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) {
+  DO(Consume("{"));
+
+  while (!TryConsume("}")) {
+    if (AtEnd()) {
+      AddError("Reached end of input in service definition (missing '}').");
+      return false;
+    }
+
+    if (!ParseServiceStatement(service)) {
+      // This statement failed to parse.  Skip it, but keep looping to parse
+      // other statements.
+      SkipStatement();
+    }
+  }
+
+  return true;
+}
+
+bool Parser::ParseServiceStatement(ServiceDescriptorProto* service) {
+  if (TryConsume(";")) {
+    // empty statement; ignore
+    return true;
+  } else if (LookingAt("option")) {
+    return ParseOption(service->mutable_options());
+  } else {
+    return ParseServiceMethod(service->add_method());
+  }
+}
+
+bool Parser::ParseServiceMethod(MethodDescriptorProto* method) {
+  DO(Consume("rpc"));
+  RecordLocation(method, DescriptorPool::ErrorCollector::NAME);
+  DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
+
+  // Parse input type.
+  DO(Consume("("));
+  RecordLocation(method, DescriptorPool::ErrorCollector::INPUT_TYPE);
+  DO(ParseUserDefinedType(method->mutable_input_type()));
+  DO(Consume(")"));
+
+  // Parse output type.
+  DO(Consume("returns"));
+  DO(Consume("("));
+  RecordLocation(method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
+  DO(ParseUserDefinedType(method->mutable_output_type()));
+  DO(Consume(")"));
+
+  if (TryConsume("{")) {
+    // Options!
+    while (!TryConsume("}")) {
+      if (AtEnd()) {
+        AddError("Reached end of input in method options (missing '}').");
+        return false;
+      }
+
+      if (TryConsume(";")) {
+        // empty statement; ignore
+      } else {
+        if (!ParseOption(method->mutable_options())) {
+          // This statement failed to parse.  Skip it, but keep looping to
+          // parse other statements.
+          SkipStatement();
+        }
+      }
+    }
+  } else {
+    DO(Consume(";"));
+  }
+
+  return true;
+}
+
+// -------------------------------------------------------------------
+
+bool Parser::ParseLabel(FieldDescriptorProto::Label* label) {
+  if (TryConsume("optional")) {
+    *label = FieldDescriptorProto::LABEL_OPTIONAL;
+    return true;
+  } else if (TryConsume("repeated")) {
+    *label = FieldDescriptorProto::LABEL_REPEATED;
+    return true;
+  } else if (TryConsume("required")) {
+    *label = FieldDescriptorProto::LABEL_REQUIRED;
+    return true;
+  } else {
+    AddError("Expected \"required\", \"optional\", or \"repeated\".");
+    // We can actually reasonably recover here by just assuming the user
+    // forgot the label altogether.
+    *label = FieldDescriptorProto::LABEL_OPTIONAL;
+    return true;
+  }
+}
+
+bool Parser::ParseType(FieldDescriptorProto::Type* type,
+                       string* type_name) {
+  TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
+  if (iter != kTypeNames.end()) {
+    *type = iter->second;
+    input_->Next();
+  } else {
+    DO(ParseUserDefinedType(type_name));
+  }
+  return true;
+}
+
+bool Parser::ParseUserDefinedType(string* type_name) {
+  type_name->clear();
+
+  TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
+  if (iter != kTypeNames.end()) {
+    // Note:  The only place enum types are allowed is for field types, but
+    //   if we are parsing a field type then we would not get here because
+    //   primitives are allowed there as well.  So this error message doesn't
+    //   need to account for enums.
+    AddError("Expected message type.");
+
+    // Pretend to accept this type so that we can go on parsing.
+    *type_name = input_->current().text;
+    input_->Next();
+    return true;
+  }
+
+  // A leading "." means the name is fully-qualified.
+  if (TryConsume(".")) type_name->append(".");
+
+  // Consume the first part of the name.
+  string identifier;
+  DO(ConsumeIdentifier(&identifier, "Expected type name."));
+  type_name->append(identifier);
+
+  // Consume more parts.
+  while (TryConsume(".")) {
+    type_name->append(".");
+    DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+    type_name->append(identifier);
+  }
+
+  return true;
+}
+
+// ===================================================================
+
+bool Parser::ParsePackage(FileDescriptorProto* file) {
+  if (file->has_package()) {
+    AddError("Multiple package definitions.");
+  }
+
+  DO(Consume("package"));
+
+  RecordLocation(file, DescriptorPool::ErrorCollector::NAME);
+
+  while (true) {
+    string identifier;
+    DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+    file->mutable_package()->append(identifier);
+    if (!TryConsume(".")) break;
+    file->mutable_package()->append(".");
+  }
+
+  DO(Consume(";"));
+  return true;
+}
+
+bool Parser::ParseImport(string* import_filename) {
+  DO(Consume("import"));
+  DO(ConsumeString(import_filename,
+    "Expected a string naming the file to import."));
+  DO(Consume(";"));
+  return true;
+}
+
+bool Parser::ParseOption(Message* options) {
+  DO(Consume("option"));
+  DO(ParseOptionAssignment(options));
+  DO(Consume(";"));
+  return true;
+}
+
+// ===================================================================
+
+SourceLocationTable::SourceLocationTable() {}
+SourceLocationTable::~SourceLocationTable() {}
+
+bool SourceLocationTable::Find(
+    const Message* descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location,
+    int* line, int* column) const {
+  const pair<int, int>* result =
+    FindOrNull(location_map_, make_pair(descriptor, location));
+  if (result == NULL) {
+    *line   = -1;
+    *column = 0;
+    return false;
+  } else {
+    *line   = result->first;
+    *column = result->second;
+    return true;
+  }
+}
+
+void SourceLocationTable::Add(
+    const Message* descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location,
+    int line, int column) {
+  location_map_[make_pair(descriptor, location)] = make_pair(line, column);
+}
+
+void SourceLocationTable::Clear() {
+  location_map_.clear();
+}
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h
new file mode 100644
index 0000000..adf6e9b
--- /dev/null
+++ b/src/google/protobuf/compiler/parser.h
@@ -0,0 +1,301 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Implements parsing of .proto files to FileDescriptorProtos.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__
+#define GOOGLE_PROTOBUF_COMPILER_PARSER_H__
+
+#include <map>
+#include <string>
+#include <utility>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/io/tokenizer.h>
+
+namespace google {
+namespace protobuf { class Message; }
+
+namespace protobuf {
+namespace compiler {
+
+// Defined in this file.
+class Parser;
+class SourceLocationTable;
+
+// Implements parsing of protocol definitions (such as .proto files).
+//
+// Note that most users will be more interested in the Importer class.
+// Parser is a lower-level class which simply converts a single .proto file
+// to a FileDescriptorProto.  It does not resolve import directives or perform
+// many other kinds of validation needed to construct a complete
+// FileDescriptor.
+class LIBPROTOBUF_EXPORT Parser {
+ public:
+  Parser();
+  ~Parser();
+
+  // Parse the entire input and construct a FileDescriptorProto representing
+  // it.  Returns true if no errors occurred, false otherwise.
+  bool Parse(io::Tokenizer* input, FileDescriptorProto* file);
+
+  // Optional fetaures:
+
+  // Requests that locations of certain definitions be recorded to the given
+  // SourceLocationTable while parsing.  This can be used to look up exact line
+  // and column numbers for errors reported by DescriptorPool during validation.
+  // Set to NULL (the default) to discard source location information.
+  void RecordSourceLocationsTo(SourceLocationTable* location_table) {
+    source_location_table_ = location_table;
+  }
+
+  // Requsets that errors be recorded to the given ErrorCollector while
+  // parsing.  Set to NULL (the default) to discard error messages.
+  void RecordErrorsTo(io::ErrorCollector* error_collector) {
+    error_collector_ = error_collector;
+  }
+
+  // Returns the identifier used in the "syntax = " declaration, if one was
+  // seen during the last call to Parse(), or the empty string otherwise.
+  const string& GetSyntaxIndentifier() { return syntax_identifier_; }
+
+  // If set true, input files will be required to begin with a syntax
+  // identifier.  Otherwise, files may omit this.  If a syntax identifier
+  // is provided, it must be 'syntax = "proto2";' and must appear at the
+  // top of this file regardless of whether or not it was required.
+  void SetRequireSyntaxIdentifier(bool value) {
+    require_syntax_identifier_ = value;
+  }
+
+ private:
+  // =================================================================
+  // Error recovery helpers
+
+  // Consume the rest of the current statement.  This consumes tokens
+  // until it sees one of:
+  //   ';'  Consumes the token and returns.
+  //   '{'  Consumes the brace then calls SkipRestOfBlock().
+  //   '}'  Returns without consuming.
+  //   EOF  Returns (can't consume).
+  // The Parser often calls SkipStatement() after encountering a syntax
+  // error.  This allows it to go on parsing the following lines, allowing
+  // it to report more than just one error in the file.
+  void SkipStatement();
+
+  // Consume the rest of the current block, including nested blocks,
+  // ending after the closing '}' is encountered and consumed, or at EOF.
+  void SkipRestOfBlock();
+
+  // -----------------------------------------------------------------
+  // Single-token consuming helpers
+  //
+  // These make parsing code more readable.
+
+  // True if the current token is TYPE_END.
+  inline bool AtEnd();
+
+  // True if the next token matches the given text.
+  inline bool LookingAt(const char* text);
+  // True if the next token is of the given type.
+  inline bool LookingAtType(io::Tokenizer::TokenType token_type);
+
+  // If the next token exactly matches the text given, consume it and return
+  // true.  Otherwise, return false without logging an error.
+  bool TryConsume(const char* text);
+
+  // These attempt to read some kind of token from the input.  If successful,
+  // they return true.  Otherwise they return false and add the given error
+  // to the error list.
+
+  // Consume a token with the exact text given.
+  bool Consume(const char* text, const char* error);
+  // Same as above, but automatically generates the error "Expected \"text\".",
+  // where "text" is the expected token text.
+  bool Consume(const char* text);
+  // Consume a token of type IDENTIFIER and store its text in "output".
+  bool ConsumeIdentifier(string* output, const char* error);
+  // Consume an integer and store its value in "output".
+  bool ConsumeInteger(int* output, const char* error);
+  // Consume a 64-bit integer and store its value in "output".  If the value
+  // is greater than max_value, an error will be reported.
+  bool ConsumeInteger64(uint64 max_value, uint64* output, const char* error);
+  // Consume a number and store its value in "output".  This will accept
+  // tokens of either INTEGER or FLOAT type.
+  bool ConsumeNumber(double* output, const char* error);
+  // Consume a string literal and store its (unescaped) value in "output".
+  bool ConsumeString(string* output, const char* error);
+
+  // -----------------------------------------------------------------
+  // Error logging helpers
+
+  // Invokes error_collector_->AddError(), if error_collector_ is not NULL.
+  void AddError(int line, int column, const string& error);
+
+  // Invokes error_collector_->AddError() with the line and column number
+  // of the current token.
+  void AddError(const string& error);
+
+  // Record the given line and column and associate it with this descriptor
+  // in the SourceLocationTable.
+  void RecordLocation(const Message* descriptor,
+                      DescriptorPool::ErrorCollector::ErrorLocation location,
+                      int line, int column);
+
+  // Record the current line and column and associate it with this descriptor
+  // in the SourceLocationTable.
+  void RecordLocation(const Message* descriptor,
+                      DescriptorPool::ErrorCollector::ErrorLocation location);
+
+  // =================================================================
+  // Parsers for various language constructs
+
+  // Parses the "syntax = \"proto2\";" line at the top of the file.  Returns
+  // false if it failed to parse or if the syntax identifier was not
+  // recognized.
+  bool ParseSyntaxIdentifier();
+
+  // These methods parse various individual bits of code.  They return
+  // false if they completely fail to parse the construct.  In this case,
+  // it is probably necessary to skip the rest of the statement to recover.
+  // However, if these methods return true, it does NOT mean that there
+  // were no errors; only that there were no *syntax* errors.  For instance,
+  // if a service method is defined using proper syntax but uses a primitive
+  // type as its input or output, ParseMethodField() still returns true
+  // and only reports the error by calling AddError().  In practice, this
+  // makes logic much simpler for the caller.
+
+  // Parse a top-level message, enum, service, etc.
+  bool ParseTopLevelStatement(FileDescriptorProto* file);
+
+  // Parse various language high-level language construrcts.
+  bool ParseMessageDefinition(DescriptorProto* message);
+  bool ParseEnumDefinition(EnumDescriptorProto* enum_type);
+  bool ParseServiceDefinition(ServiceDescriptorProto* service);
+  bool ParsePackage(FileDescriptorProto* file);
+  bool ParseImport(string* import_filename);
+  bool ParseOption(Message* options);
+
+  // These methods parse the contents of a message, enum, or service type and
+  // add them to the given object.  They consume the entire block including
+  // the beginning and ending brace.
+  bool ParseMessageBlock(DescriptorProto* message);
+  bool ParseEnumBlock(EnumDescriptorProto* enum_type);
+  bool ParseServiceBlock(ServiceDescriptorProto* service);
+
+  // Parse one statement within a message, enum, or service block, inclunding
+  // final semicolon.
+  bool ParseMessageStatement(DescriptorProto* message);
+  bool ParseEnumStatement(EnumDescriptorProto* message);
+  bool ParseServiceStatement(ServiceDescriptorProto* message);
+
+  // Parse a field of a message.  If the field is a group, its type will be
+  // added to "messages".
+  bool ParseMessageField(FieldDescriptorProto* field,
+                         RepeatedPtrField<DescriptorProto>* messages);
+
+  // Parse an "extensions" declaration.
+  bool ParseExtensions(DescriptorProto* message);
+
+  // Parse an "extend" declaration.
+  bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
+                   RepeatedPtrField<DescriptorProto>* messages);
+
+  // Parse a single enum value within an enum block.
+  bool ParseEnumConstant(EnumValueDescriptorProto* enum_value);
+
+  // Parse a single method within a service definition.
+  bool ParseServiceMethod(MethodDescriptorProto* method);
+
+  // Parse "required", "optional", or "repeated" and fill in "label"
+  // with the value.
+  bool ParseLabel(FieldDescriptorProto::Label* label);
+
+  // Parse a type name and fill in "type" (if it is a primitive) or
+  // "type_name" (if it is not) with the type parsed.
+  bool ParseType(FieldDescriptorProto::Type* type,
+                 string* type_name);
+  // Parse a user-defined type and fill in "type_name" with the name.
+  // If a primitive type is named, it is treated as an error.
+  bool ParseUserDefinedType(string* type_name);
+
+  // Parses field options, i.e. the stuff in square brackets at the end
+  // of a field definition.  Also parses default value.
+  bool ParseFieldOptions(FieldDescriptorProto* field);
+
+  // Parse the "default" option.  This needs special handling because its
+  // type is the field's type.
+  bool ParseDefaultAssignment(FieldDescriptorProto* field);
+
+  // Parse a single option name/value pair, e.g. "ctype = CORD".  The name
+  // identifies a field of the given Message, and the value of that field
+  // is set to the parsed value.
+  bool ParseOptionAssignment(Message* options);
+
+  // =================================================================
+
+  io::Tokenizer* input_;
+  io::ErrorCollector* error_collector_;
+  SourceLocationTable* source_location_table_;
+  bool had_errors_;
+  bool require_syntax_identifier_;
+  string syntax_identifier_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
+};
+
+// A table mapping (descriptor, ErrorLocation) pairs -- as reported by
+// DescriptorPool when validating descriptors -- to line and column numbers
+// within the original source code.
+class LIBPROTOBUF_EXPORT SourceLocationTable {
+ public:
+  SourceLocationTable();
+  ~SourceLocationTable();
+
+  // Finds the precise location of the given error and fills in *line and
+  // *column with the line and column numbers.  If not found, sets *line to
+  // -1 and *column to 0 (since line = -1 is used to mean "error has no exact
+  // location" in the ErrorCollector interface).  Returns true if found, false
+  // otherwise.
+  bool Find(const Message* descriptor,
+            DescriptorPool::ErrorCollector::ErrorLocation location,
+            int* line, int* column) const;
+
+  // Adds a location to the table.
+  void Add(const Message* descriptor,
+           DescriptorPool::ErrorCollector::ErrorLocation location,
+           int line, int column);
+
+  // Clears the contents of the table.
+  void Clear();
+
+ private:
+  typedef map<
+    pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>,
+    pair<int, int> > LocationMap;
+  LocationMap location_map_;
+};
+
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_PARSER_H__
diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc
new file mode 100644
index 0000000..489106b
--- /dev/null
+++ b/src/google/protobuf/compiler/parser_unittest.cc
@@ -0,0 +1,1142 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <vector>
+#include <algorithm>
+
+#include <google/protobuf/compiler/parser.h>
+
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+
+class MockErrorCollector : public io::ErrorCollector {
+ public:
+  MockErrorCollector() {}
+  ~MockErrorCollector() {}
+
+  string text_;
+
+  // implements ErrorCollector ---------------------------------------
+  void AddError(int line, int column, const string& message) {
+    strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
+                                 line, column, message);
+  }
+};
+
+class MockValidationErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+  MockValidationErrorCollector(const SourceLocationTable& source_locations,
+                               io::ErrorCollector* wrapped_collector)
+    : source_locations_(source_locations),
+      wrapped_collector_(wrapped_collector) {}
+  ~MockValidationErrorCollector() {}
+
+  // implements ErrorCollector ---------------------------------------
+  void AddError(const string& filename,
+                const string& element_name,
+                const Message* descriptor,
+                ErrorLocation location,
+                const string& message) {
+    int line, column;
+    source_locations_.Find(descriptor, location, &line, &column);
+    wrapped_collector_->AddError(line, column, message);
+  }
+
+ private:
+  const SourceLocationTable& source_locations_;
+  io::ErrorCollector* wrapped_collector_;
+};
+
+class ParserTest : public testing::Test {
+ protected:
+  ParserTest()
+    : require_syntax_identifier_(false) {}
+
+  // Set up the parser to parse the given text.
+  void SetupParser(const char* text) {
+    raw_input_.reset(new io::ArrayInputStream(text, strlen(text)));
+    input_.reset(new io::Tokenizer(raw_input_.get(), &error_collector_));
+    parser_.reset(new Parser());
+    parser_->RecordErrorsTo(&error_collector_);
+    parser_->SetRequireSyntaxIdentifier(require_syntax_identifier_);
+  }
+
+  // Parse the input and expect that the resulting FileDescriptorProto matches
+  // the given output.  The output is a FileDescriptorProto in protocol buffer
+  // text format.
+  void ExpectParsesTo(const char* input, const char* output) {
+    SetupParser(input);
+    FileDescriptorProto actual, expected;
+
+    parser_->Parse(input_.get(), &actual);
+    EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+    ASSERT_EQ("", error_collector_.text_);
+
+    // Parse the ASCII representation in order to canonicalize it.  We could
+    // just compare directly to actual.DebugString(), but that would require
+    // that the caller precisely match the formatting that DebugString()
+    // produces.
+    ASSERT_TRUE(TextFormat::ParseFromString(output, &expected));
+
+    // Compare by comparing debug strings.
+    // TODO(kenton):  Use differencer, once it is available.
+    EXPECT_EQ(expected.DebugString(), actual.DebugString());
+  }
+
+  // Parse the text and expect that the given errors are reported.
+  void ExpectHasErrors(const char* text, const char* expected_errors) {
+    ExpectHasEarlyExitErrors(text, expected_errors);
+    EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+  }
+
+  // Same as above but does not expect that the parser parses the complete
+  // input.
+  void ExpectHasEarlyExitErrors(const char* text, const char* expected_errors) {
+    SetupParser(text);
+    FileDescriptorProto file;
+    parser_->Parse(input_.get(), &file);
+    EXPECT_EQ(expected_errors, error_collector_.text_);
+  }
+
+  // Parse the text as a file and validate it (with a DescriptorPool), and
+  // expect that the validation step reports the given errors.
+  void ExpectHasValidationErrors(const char* text,
+                                 const char* expected_errors) {
+    SetupParser(text);
+    SourceLocationTable source_locations;
+    parser_->RecordSourceLocationsTo(&source_locations);
+
+    FileDescriptorProto file;
+    file.set_name("foo.proto");
+    parser_->Parse(input_.get(), &file);
+    EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+    ASSERT_EQ("", error_collector_.text_);
+
+    MockValidationErrorCollector validation_error_collector(
+      source_locations, &error_collector_);
+    EXPECT_TRUE(pool_.BuildFileCollectingErrors(
+      file, &validation_error_collector) == NULL);
+    EXPECT_EQ(expected_errors, error_collector_.text_);
+  }
+
+  MockErrorCollector error_collector_;
+  DescriptorPool pool_;
+
+  scoped_ptr<io::ZeroCopyInputStream> raw_input_;
+  scoped_ptr<io::Tokenizer> input_;
+  scoped_ptr<Parser> parser_;
+  bool require_syntax_identifier_;
+};
+
+// ===================================================================
+
+typedef ParserTest ParseMessageTest;
+
+TEST_F(ParseMessageTest, SimpleMessage) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  required int32 foo = 1;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, ImplicitSyntaxIdentifier) {
+  require_syntax_identifier_ = false;
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  required int32 foo = 1;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+    "}");
+  EXPECT_EQ("proto2", parser_->GetSyntaxIndentifier());
+}
+
+TEST_F(ParseMessageTest, ExplicitSyntaxIdentifier) {
+  ExpectParsesTo(
+    "syntax = \"proto2\";\n"
+    "message TestMessage {\n"
+    "  required int32 foo = 1;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+    "}");
+  EXPECT_EQ("proto2", parser_->GetSyntaxIndentifier());
+}
+
+TEST_F(ParseMessageTest, ExplicitRequiredSyntaxIdentifier) {
+  require_syntax_identifier_ = true;
+  ExpectParsesTo(
+    "syntax = \"proto2\";\n"
+    "message TestMessage {\n"
+    "  required int32 foo = 1;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+    "}");
+  EXPECT_EQ("proto2", parser_->GetSyntaxIndentifier());
+}
+
+TEST_F(ParseMessageTest, SimpleFields) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  required int32 foo = 15;\n"
+    "  optional int32 bar = 34;\n"
+    "  repeated int32 baz = 3;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:15 }"
+    "  field { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:34 }"
+    "  field { name:\"baz\" label:LABEL_REPEATED type:TYPE_INT32 number:3  }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, PrimitiveFieldTypes) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  required int32    foo = 1;\n"
+    "  required int64    foo = 1;\n"
+    "  required uint32   foo = 1;\n"
+    "  required uint64   foo = 1;\n"
+    "  required sint32   foo = 1;\n"
+    "  required sint64   foo = 1;\n"
+    "  required fixed32  foo = 1;\n"
+    "  required fixed64  foo = 1;\n"
+    "  required sfixed32 foo = 1;\n"
+    "  required sfixed64 foo = 1;\n"
+    "  required float    foo = 1;\n"
+    "  required double   foo = 1;\n"
+    "  required string   foo = 1;\n"
+    "  required bytes    foo = 1;\n"
+    "  required bool     foo = 1;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32    number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT64    number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT32   number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT64   number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT32   number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT64   number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED32  number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED64  number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED32 number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED64 number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FLOAT    number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_DOUBLE   number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_STRING   number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BYTES    number:1 }"
+    "  field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BOOL     number:1 }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, FieldDefaults) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  required int32  foo = 1 [default=  1  ];\n"
+    "  required int32  foo = 1 [default= -2  ];\n"
+    "  required int64  foo = 1 [default=  3  ];\n"
+    "  required int64  foo = 1 [default= -4  ];\n"
+    "  required uint32 foo = 1 [default=  5  ];\n"
+    "  required uint64 foo = 1 [default=  6  ];\n"
+    "  required float  foo = 1 [default=  7.5];\n"
+    "  required float  foo = 1 [default= -8.5];\n"
+    "  required float  foo = 1 [default=  9  ];\n"
+    "  required double foo = 1 [default= 10.5];\n"
+    "  required double foo = 1 [default=-11.5];\n"
+    "  required double foo = 1 [default= 12  ];\n"
+    "  required string foo = 1 [default='13\\001'];\n"
+    "  required bytes  foo = 1 [default='14\\002'];\n"
+    "  required bool   foo = 1 [default=true ];\n"
+    "  required Foo    foo = 1 [default=FOO  ];\n"
+
+    "  required int32  foo = 1 [default= 0x7FFFFFFF];\n"
+    "  required int32  foo = 1 [default=-0x80000000];\n"
+    "  required uint32 foo = 1 [default= 0xFFFFFFFF];\n"
+    "  required int64  foo = 1 [default= 0x7FFFFFFFFFFFFFFF];\n"
+    "  required int64  foo = 1 [default=-0x8000000000000000];\n"
+    "  required uint64 foo = 1 [default= 0xFFFFFFFFFFFFFFFF];\n"
+    "  required double foo = 1 [default= 0xabcd];\n"
+    "}\n",
+
+#define ETC "name:\"foo\" label:LABEL_REQUIRED number:1"
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { type:TYPE_INT32   default_value:\"1\"         "ETC" }"
+    "  field { type:TYPE_INT32   default_value:\"-2\"        "ETC" }"
+    "  field { type:TYPE_INT64   default_value:\"3\"         "ETC" }"
+    "  field { type:TYPE_INT64   default_value:\"-4\"        "ETC" }"
+    "  field { type:TYPE_UINT32  default_value:\"5\"         "ETC" }"
+    "  field { type:TYPE_UINT64  default_value:\"6\"         "ETC" }"
+    "  field { type:TYPE_FLOAT   default_value:\"7.5\"       "ETC" }"
+    "  field { type:TYPE_FLOAT   default_value:\"-8.5\"      "ETC" }"
+    "  field { type:TYPE_FLOAT   default_value:\"9\"         "ETC" }"
+    "  field { type:TYPE_DOUBLE  default_value:\"10.5\"      "ETC" }"
+    "  field { type:TYPE_DOUBLE  default_value:\"-11.5\"     "ETC" }"
+    "  field { type:TYPE_DOUBLE  default_value:\"12\"        "ETC" }"
+    "  field { type:TYPE_STRING  default_value:\"13\\001\"   "ETC" }"
+    "  field { type:TYPE_BYTES   default_value:\"14\\\\002\" "ETC" }"
+    "  field { type:TYPE_BOOL    default_value:\"true\"      "ETC" }"
+    "  field { type_name:\"Foo\" default_value:\"FOO\"       "ETC" }"
+
+    "  field { type:TYPE_INT32   default_value:\"2147483647\"           "ETC" }"
+    "  field { type:TYPE_INT32   default_value:\"-2147483648\"          "ETC" }"
+    "  field { type:TYPE_UINT32  default_value:\"4294967295\"           "ETC" }"
+    "  field { type:TYPE_INT64   default_value:\"9223372036854775807\"  "ETC" }"
+    "  field { type:TYPE_INT64   default_value:\"-9223372036854775808\" "ETC" }"
+    "  field { type:TYPE_UINT64  default_value:\"18446744073709551615\" "ETC" }"
+    "  field { type:TYPE_DOUBLE  default_value:\"43981\"                "ETC" }"
+    "}");
+#undef ETC
+}
+
+TEST_F(ParseMessageTest, FieldOptions) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  optional string foo = 1 [ctype=CORD];\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_STRING number:1"
+    "          options { ctype:CORD } }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, Group) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  optional group TestGroup = 1 {};\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  nested_type { name: \"TestGroup\" }"
+    "  field { name:\"testgroup\" label:LABEL_OPTIONAL number:1"
+    "          type:TYPE_GROUP type_name: \"TestGroup\" }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, NestedMessage) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  message Nested {}\n"
+    "  optional Nested test_nested = 1;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  nested_type { name: \"Nested\" }"
+    "  field { name:\"test_nested\" label:LABEL_OPTIONAL number:1"
+    "          type_name: \"Nested\" }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, NestedEnum) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  enum NestedEnum {}\n"
+    "  optional NestedEnum test_enum = 1;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  enum_type { name: \"NestedEnum\" }"
+    "  field { name:\"test_enum\" label:LABEL_OPTIONAL number:1"
+    "          type_name: \"NestedEnum\" }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, ExtensionRange) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  extensions 10 to 19;\n"
+    "  extensions 30 to max;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  extension_range { start:10 end:20        }"
+    "  extension_range { start:30 end:536870912 }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, CompoundExtensionRange) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  extensions 2, 15, 9 to 11, 100 to max, 3;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  extension_range { start:2   end:3         }"
+    "  extension_range { start:15  end:16        }"
+    "  extension_range { start:9   end:12        }"
+    "  extension_range { start:100 end:536870912 }"
+    "  extension_range { start:3   end:4         }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, Extensions) {
+  ExpectParsesTo(
+    "extend Extendee1 { optional int32 foo = 12; }\n"
+    "extend Extendee2 { repeated TestMessage bar = 22; }\n",
+
+    "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
+    "            extendee: \"Extendee1\" } "
+    "extension { name:\"bar\" label:LABEL_REPEATED number:22"
+    "            type_name:\"TestMessage\" extendee: \"Extendee2\" }");
+}
+
+TEST_F(ParseMessageTest, ExtensionsInMessageScope) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  extend Extendee1 { optional int32 foo = 12; }\n"
+    "  extend Extendee2 { repeated TestMessage bar = 22; }\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
+    "              extendee: \"Extendee1\" }"
+    "  extension { name:\"bar\" label:LABEL_REPEATED number:22"
+    "              type_name:\"TestMessage\" extendee: \"Extendee2\" }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, MultipleExtensionsOneExtendee) {
+  ExpectParsesTo(
+    "extend Extendee1 {\n"
+    "  optional int32 foo = 12;\n"
+    "  repeated TestMessage bar = 22;\n"
+    "}\n",
+
+    "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
+    "            extendee: \"Extendee1\" } "
+    "extension { name:\"bar\" label:LABEL_REPEATED number:22"
+    "            type_name:\"TestMessage\" extendee: \"Extendee1\" }");
+}
+
+// ===================================================================
+
+typedef ParserTest ParseEnumTest;
+
+TEST_F(ParseEnumTest, SimpleEnum) {
+  ExpectParsesTo(
+    "enum TestEnum {\n"
+    "  FOO = 0;\n"
+    "}\n",
+
+    "enum_type {"
+    "  name: \"TestEnum\""
+    "  value { name:\"FOO\" number:0 }"
+    "}");
+}
+
+TEST_F(ParseEnumTest, Values) {
+  ExpectParsesTo(
+    "enum TestEnum {\n"
+    "  FOO = 13;\n"
+    "  BAR = -10;\n"
+    "  BAZ = 500;\n"
+    "}\n",
+
+    "enum_type {"
+    "  name: \"TestEnum\""
+    "  value { name:\"FOO\" number:13 }"
+    "  value { name:\"BAR\" number:-10 }"
+    "  value { name:\"BAZ\" number:500 }"
+    "}");
+}
+
+// ===================================================================
+
+typedef ParserTest ParseServiceTest;
+
+TEST_F(ParseServiceTest, SimpleService) {
+  ExpectParsesTo(
+    "service TestService {\n"
+    "  rpc Foo(In) returns (Out);\n"
+    "}\n",
+
+    "service {"
+    "  name: \"TestService\""
+    "  method { name:\"Foo\" input_type:\"In\" output_type:\"Out\" }"
+    "}");
+}
+
+TEST_F(ParseServiceTest, Methods) {
+  ExpectParsesTo(
+    "service TestService {\n"
+    "  rpc Foo(In1) returns (Out1);\n"
+    "  rpc Bar(In2) returns (Out2);\n"
+    "  rpc Baz(In3) returns (Out3);\n"
+    "}\n",
+
+    "service {"
+    "  name: \"TestService\""
+    "  method { name:\"Foo\" input_type:\"In1\" output_type:\"Out1\" }"
+    "  method { name:\"Bar\" input_type:\"In2\" output_type:\"Out2\" }"
+    "  method { name:\"Baz\" input_type:\"In3\" output_type:\"Out3\" }"
+    "}");
+}
+
+// ===================================================================
+// imports and packages
+
+typedef ParserTest ParseMiscTest;
+
+TEST_F(ParseMiscTest, ParseImport) {
+  ExpectParsesTo(
+    "import \"foo/bar/baz.proto\";\n",
+    "dependency: \"foo/bar/baz.proto\"");
+}
+
+TEST_F(ParseMiscTest, ParseMultipleImports) {
+  ExpectParsesTo(
+    "import \"foo.proto\";\n"
+    "import \"bar.proto\";\n"
+    "import \"baz.proto\";\n",
+    "dependency: \"foo.proto\""
+    "dependency: \"bar.proto\""
+    "dependency: \"baz.proto\"");
+}
+
+TEST_F(ParseMiscTest, ParsePackage) {
+  ExpectParsesTo(
+    "package foo.bar.baz;\n",
+    "package: \"foo.bar.baz\"");
+}
+
+TEST_F(ParseMiscTest, ParsePackageWithSpaces) {
+  ExpectParsesTo(
+    "package foo   .   bar.  \n"
+    "  baz;\n",
+    "package: \"foo.bar.baz\"");
+}
+
+// ===================================================================
+// options
+
+TEST_F(ParseMiscTest, ParseFileOptions) {
+  ExpectParsesTo(
+    "option java_package = \"com.google.foo\";\n"
+    "option optimize_for = CODE_SIZE;",
+
+    "options {"
+    "  java_package: \"com.google.foo\""
+    "  optimize_for: CODE_SIZE"
+    "}");
+}
+
+// TODO(kenton):  We'd like to be able to test all possible option types,
+//   but we are unable to do so here because we can only test the options
+//   that actually exist, which currently doesn't cover everything.  Perhaps
+//   we can solve this in the future by allowing options to be extended, then
+//   defining extensions of every type?
+
+// ===================================================================
+// Error tests
+//
+// There are a very large number of possible errors that the parser could
+// report, so it's infeasible to test every single one of them.  Instead,
+// we test each unique call to AddError() in parser.h.  This does not mean
+// we are testing every possible error that Parser can generate because
+// each variant of the Consume() helper only counts as one unique call to
+// AddError().
+
+typedef ParserTest ParseErrorTest;
+
+TEST_F(ParseErrorTest, MissingSyntaxIdentifier) {
+  require_syntax_identifier_ = true;
+  ExpectHasEarlyExitErrors(
+    "message TestMessage {}",
+    "0:0: File must begin with 'syntax = \"proto2\";'.\n");
+  EXPECT_EQ("", parser_->GetSyntaxIndentifier());
+}
+
+TEST_F(ParseErrorTest, UnknownSyntaxIdentifier) {
+  ExpectHasEarlyExitErrors(
+    "syntax = \"no_such_syntax\";",
+    "0:9: Unrecognized syntax identifier \"no_such_syntax\".  This parser "
+      "only recognizes \"proto2\".\n");
+  EXPECT_EQ("no_such_syntax", parser_->GetSyntaxIndentifier());
+}
+
+TEST_F(ParseErrorTest, SimpleSyntaxError) {
+  ExpectHasErrors(
+    "message TestMessage @#$ { blah }",
+    "0:20: Expected \"{\".\n");
+  EXPECT_EQ("proto2", parser_->GetSyntaxIndentifier());
+}
+
+TEST_F(ParseErrorTest, ExpectedTopLevel) {
+  ExpectHasErrors(
+    "blah;",
+    "0:0: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(ParseErrorTest, UnmatchedCloseBrace) {
+  // This used to cause an infinite loop.  Doh.
+  ExpectHasErrors(
+    "}",
+    "0:0: Expected top-level statement (e.g. \"message\").\n"
+    "0:0: Unmatched \"}\".\n");
+}
+
+// -------------------------------------------------------------------
+// Message errors
+
+TEST_F(ParseErrorTest, MessageMissingName) {
+  ExpectHasErrors(
+    "message {}",
+    "0:8: Expected message name.\n");
+}
+
+TEST_F(ParseErrorTest, MessageMissingBody) {
+  ExpectHasErrors(
+    "message TestMessage;",
+    "0:19: Expected \"{\".\n");
+}
+
+TEST_F(ParseErrorTest, EofInMessage) {
+  ExpectHasErrors(
+    "message TestMessage {",
+    "0:21: Reached end of input in message definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, MissingFieldNumber) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional int32 foo;\n"
+    "}\n",
+    "1:20: Missing field number.\n");
+}
+
+TEST_F(ParseErrorTest, ExpectedFieldNumber) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional int32 foo = ;\n"
+    "}\n",
+    "1:23: Expected field number.\n");
+}
+
+TEST_F(ParseErrorTest, FieldNumberOutOfRange) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional int32 foo = 0x100000000;\n"
+    "}\n",
+    "1:23: Integer out of range.\n");
+}
+
+TEST_F(ParseErrorTest, MissingLabel) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  int32 foo = 1;\n"
+    "}\n",
+    "1:2: Expected \"required\", \"optional\", or \"repeated\".\n");
+}
+
+TEST_F(ParseErrorTest, ExpectedOptionName) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [];\n"
+    "}\n",
+    "1:27: Expected option name.\n");
+}
+
+TEST_F(ParseErrorTest, UnknownOption) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [nosuchoption=5];\n"
+    "}\n",
+    "1:27: Unknown option: nosuchoption\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueTypeMismatch) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [default=true];\n"
+    "}\n",
+    "1:35: Expected integer.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueNotBoolean) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional bool foo = 1 [default=blah];\n"
+    "}\n",
+    "1:33: Expected \"true\" or \"false\".\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueNotString) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional string foo = 1 [default=1];\n"
+    "}\n",
+    "1:35: Expected string.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueUnsignedNegative) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [default=-1];\n"
+    "}\n",
+    "1:36: Unsigned field can't have negative default value.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueTooLarge) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional int32  foo = 1 [default= 0x80000000];\n"
+    "  optional int32  foo = 1 [default=-0x80000001];\n"
+    "  optional uint32 foo = 1 [default= 0x100000000];\n"
+    "  optional int64  foo = 1 [default= 0x80000000000000000];\n"
+    "  optional int64  foo = 1 [default=-0x80000000000000001];\n"
+    "  optional uint64 foo = 1 [default= 0x100000000000000000];\n"
+    "}\n",
+    "1:36: Integer out of range.\n"
+    "2:36: Integer out of range.\n"
+    "3:36: Integer out of range.\n"
+    "4:36: Integer out of range.\n"
+    "5:36: Integer out of range.\n"
+    "6:36: Integer out of range.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueMissing) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [default=];\n"
+    "}\n",
+    "1:35: Expected integer.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueForGroup) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional group Foo = 1 [default=blah] {}\n"
+    "}\n",
+    "1:34: Messages can't have default values.\n");
+}
+
+TEST_F(ParseErrorTest, DuplicateDefaultValue) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [default=1,default=2];\n"
+    "}\n",
+    "1:37: Already set option \"default\".\n");
+}
+
+TEST_F(ParseErrorTest, GroupNotCapitalized) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional group foo = 1 {}\n"
+    "}\n",
+    "1:17: Group names must start with a capital letter.\n");
+}
+
+TEST_F(ParseErrorTest, GroupMissingBody) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional group Foo = 1;\n"
+    "}\n",
+    "1:24: Missing group body.\n");
+}
+
+TEST_F(ParseErrorTest, ExtendingPrimitive) {
+  ExpectHasErrors(
+    "extend int32 { optional string foo = 4; }\n",
+    "0:7: Expected message type.\n");
+}
+
+TEST_F(ParseErrorTest, ErrorInExtension) {
+  ExpectHasErrors(
+    "message Foo { extensions 100 to 199; }\n"
+    "extend Foo { optional string foo; }\n",
+    "1:32: Missing field number.\n");
+}
+
+TEST_F(ParseErrorTest, MultipleParseErrors) {
+  // When a statement has a parse error, the parser should be able to continue
+  // parsing at the next statement.
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional int32 foo;\n"
+    "  !invalid statement ending in a block { blah blah { blah } blah }\n"
+    "  optional int32 bar = 3 {}\n"
+    "}\n",
+    "1:20: Missing field number.\n"
+    "2:2: Expected \"required\", \"optional\", or \"repeated\".\n"
+    "2:2: Expected type name.\n"
+    "3:25: Expected \";\".\n");
+}
+
+// -------------------------------------------------------------------
+// Enum errors
+
+TEST_F(ParseErrorTest, EofInEnum) {
+  ExpectHasErrors(
+    "enum TestEnum {",
+    "0:15: Reached end of input in enum definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, EnumValueMissingNumber) {
+  ExpectHasErrors(
+    "enum TestEnum {\n"
+    "  FOO;\n"
+    "}\n",
+    "1:5: Missing numeric value for enum constant.\n");
+}
+
+// -------------------------------------------------------------------
+// Service errors
+
+TEST_F(ParseErrorTest, EofInService) {
+  ExpectHasErrors(
+    "service TestService {",
+    "0:21: Reached end of input in service definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, ServiceMethodPrimitiveParams) {
+  ExpectHasErrors(
+    "service TestService {\n"
+    "  rpc Foo(int32) returns (string);\n"
+    "}\n",
+    "1:10: Expected message type.\n"
+    "1:26: Expected message type.\n");
+}
+
+TEST_F(ParseErrorTest, EofInMethodOptions) {
+  ExpectHasErrors(
+    "service TestService {\n"
+    "  rpc Foo(Bar) returns(Bar) {",
+    "1:29: Reached end of input in method options (missing '}').\n"
+    "1:29: Reached end of input in service definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, PrimitiveMethodInput) {
+  ExpectHasErrors(
+    "service TestService {\n"
+    "  rpc Foo(int32) returns(Bar);\n"
+    "}\n",
+    "1:10: Expected message type.\n");
+}
+
+TEST_F(ParseErrorTest, MethodOptionTypeError) {
+  // This used to cause an infinite loop.
+  ExpectHasErrors(
+    "message Baz {}\n"
+    "service Foo {\n"
+    "  rpc Bar(Baz) returns(Baz) { option invalid syntax; }\n"
+    "}\n",
+    "2:37: Unknown option: invalid\n");
+}
+
+// -------------------------------------------------------------------
+// Import and package errors
+
+TEST_F(ParseErrorTest, ImportNotQuoted) {
+  ExpectHasErrors(
+    "import foo;\n",
+    "0:7: Expected a string naming the file to import.\n");
+}
+
+TEST_F(ParseErrorTest, MultiplePackagesInFile) {
+  ExpectHasErrors(
+    "package foo;\n"
+    "package bar;\n",
+    "1:0: Multiple package definitions.\n");
+}
+
+// -------------------------------------------------------------------
+// Option errors
+
+TEST_F(ParseErrorTest, OptionWrongType) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional string foo = 1 [ctype=1];\n"
+    "}\n",
+    "1:33: Expected enum value.\n");
+}
+
+TEST_F(ParseErrorTest, DupOption) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [ctype=CORD,ctype=CORD];\n"
+    "}\n",
+    "1:38: Option \"ctype\" was already set.\n");
+}
+
+TEST_F(ParseErrorTest, NotMessageOption) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [ctype.blah=1];\n"
+    "}\n",
+    "1:32: Option \"ctype\" is an atomic type, not a message.\n");
+}
+
+// TODO(kenton):  Test errors for all possible option types (see TODO above,
+//   under the option parsing tests).
+
+// ===================================================================
+// Test that errors detected by DescriptorPool correctly report line and
+// column numbers.  We have one test for every call to RecordLocation() in
+// parser.cc.
+
+typedef ParserTest ParserValidationErrorTest;
+
+TEST_F(ParserValidationErrorTest, PackageNameError) {
+  // Create another file which defines symbol "foo".
+  FileDescriptorProto other_file;
+  other_file.set_name("bar.proto");
+  other_file.add_message_type()->set_name("foo");
+  EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
+
+  // Now try to define it as a package.
+  ExpectHasValidationErrors(
+    "package foo.bar;",
+    "0:8: \"foo\" is already defined (as something other than a package) "
+      "in file \"bar.proto\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, MessageNameError) {
+  ExpectHasValidationErrors(
+    "message Foo {}\n"
+    "message Foo {}\n",
+    "1:8: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldNameError) {
+  ExpectHasValidationErrors(
+    "message Foo {\n"
+    "  optional int32 bar = 1;\n"
+    "  optional int32 bar = 2;\n"
+    "}\n",
+    "2:17: \"bar\" is already defined in \"Foo\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldTypeError) {
+  ExpectHasValidationErrors(
+    "message Foo {\n"
+    "  optional Baz bar = 1;\n"
+    "}\n",
+    "1:11: \"Baz\" is not defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldNumberError) {
+  ExpectHasValidationErrors(
+    "message Foo {\n"
+    "  optional int32 bar = 0;\n"
+    "}\n",
+    "1:23: Field numbers must be positive integers.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldExtendeeError) {
+  ExpectHasValidationErrors(
+    "extend Baz { optional int32 bar = 1; }\n",
+    "0:7: \"Baz\" is not defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldDefaultValueError) {
+  ExpectHasValidationErrors(
+    "enum Baz { QUX = 1; }\n"
+    "message Foo {\n"
+    "  optional Baz bar = 1 [default=NO_SUCH_VALUE];\n"
+    "}\n",
+    "2:32: Enum type \"Baz\" has no value named \"NO_SUCH_VALUE\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, ExtensionRangeNumberError) {
+  ExpectHasValidationErrors(
+    "message Foo {\n"
+    "  extensions 0;\n"
+    "}\n",
+    "1:13: Extension numbers must be positive integers.\n");
+}
+
+TEST_F(ParserValidationErrorTest, EnumNameError) {
+  ExpectHasValidationErrors(
+    "enum Foo {A = 1;}\n"
+    "enum Foo {B = 1;}\n",
+    "1:5: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, EnumValueNameError) {
+  ExpectHasValidationErrors(
+    "enum Foo {\n"
+    "  BAR = 1;\n"
+    "  BAR = 1;\n"
+    "}\n",
+    "2:2: \"BAR\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, ServiceNameError) {
+  ExpectHasValidationErrors(
+    "service Foo {}\n"
+    "service Foo {}\n",
+    "1:8: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, MethodNameError) {
+  ExpectHasValidationErrors(
+    "message Baz {}\n"
+    "service Foo {\n"
+    "  rpc Bar(Baz) returns(Baz);\n"
+    "  rpc Bar(Baz) returns(Baz);\n"
+    "}\n",
+    "3:6: \"Bar\" is already defined in \"Foo\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, MethodInputTypeError) {
+  ExpectHasValidationErrors(
+    "message Baz {}\n"
+    "service Foo {\n"
+    "  rpc Bar(Qux) returns(Baz);\n"
+    "}\n",
+    "2:10: \"Qux\" is not defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, MethodOutputTypeError) {
+  ExpectHasValidationErrors(
+    "message Baz {}\n"
+    "service Foo {\n"
+    "  rpc Bar(Baz) returns(Qux);\n"
+    "}\n",
+    "2:23: \"Qux\" is not defined.\n");
+}
+
+// ===================================================================
+// Test that the output from FileDescriptor::DebugString() (and all other
+// descriptor types) is parseable, and results in the same Descriptor
+// definitions again afoter parsing (not, however, that the order of messages
+// cannot be guaranteed to be the same)
+
+typedef ParserTest ParseDecriptorDebugTest;
+
+class CompareDescriptorNames {
+ public:
+  bool operator()(const DescriptorProto* left, const DescriptorProto* right) {
+    return left->name() < right->name();
+  }
+};
+
+// Sorts nested DescriptorProtos of a DescriptoProto, by name.
+void SortMessages(DescriptorProto *descriptor_proto) {
+  int size = descriptor_proto->nested_type_size();
+  // recursively sort; we can't guarantee the order of nested messages either
+  for (int i = 0; i < size; ++i) {
+    SortMessages(descriptor_proto->mutable_nested_type(i));
+  }
+  DescriptorProto **data =
+    descriptor_proto->mutable_nested_type()->mutable_data();
+  sort(data, data + size, CompareDescriptorNames());
+}
+
+// Sorts DescriptorProtos belonging to a FileDescriptorProto, by name.
+void SortMessages(FileDescriptorProto *file_descriptor_proto) {
+  int size = file_descriptor_proto->message_type_size();
+  // recursively sort; we can't guarantee the order of nested messages either
+  for (int i = 0; i < size; ++i) {
+    SortMessages(file_descriptor_proto->mutable_message_type(i));
+  }
+  DescriptorProto **data =
+    file_descriptor_proto->mutable_message_type()->mutable_data();
+  sort(data, data + size, CompareDescriptorNames());
+}
+
+TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) {
+  const FileDescriptor* original_file =
+     protobuf_unittest::TestAllTypes::descriptor()->file();
+  FileDescriptorProto expected;
+  original_file->CopyTo(&expected);
+
+  // Get the DebugString of the unittest.proto FileDecriptor, which includes
+  // all other descriptor types
+  string debug_string = original_file->DebugString();
+
+  // Parse the debug string
+  SetupParser(debug_string.c_str());
+  FileDescriptorProto parsed;
+  parser_->Parse(input_.get(), &parsed);
+  EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+  ASSERT_EQ("", error_collector_.text_);
+
+  // We now have a FileDescriptorProto, but to compare with the expected we
+  // need to link to a FileDecriptor, then output back to a proto. We'll
+  // also need to give it the same name as the original.
+  parsed.set_name("google/protobuf/unittest.proto");
+  // We need the imported dependency before we can build our parsed proto
+  const FileDescriptor* import =
+       protobuf_unittest_import::ImportMessage::descriptor()->file();
+  FileDescriptorProto import_proto;
+  import->CopyTo(&import_proto);
+  ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
+  const FileDescriptor* actual = pool_.BuildFile(parsed);
+  parsed.Clear();
+  actual->CopyTo(&parsed);
+  ASSERT_TRUE(actual != NULL);
+
+  // The messages might be in different orders, making them hard to compare.
+  // So, sort the messages in the descriptor protos (including nested messages,
+  // recursively).
+  SortMessages(&expected);
+  SortMessages(&parsed);
+
+  // I really wanted to use StringDiff here for the debug output on fail,
+  // but the strings are too long for it, and if I increase its max size,
+  // we get a memory allocation failure :(
+  EXPECT_EQ(expected.DebugString(), parsed.DebugString());
+}
+
+// ===================================================================
+
+}  // anonymous namespace
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
new file mode 100644
index 0000000..e117138
--- /dev/null
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -0,0 +1,794 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: robinson@google.com (Will Robinson)
+//
+// This module outputs pure-Python protocol message classes that will
+// largely be constructed at runtime via the metaclass in reflection.py.
+// In other words, our job is basically to output a Python equivalent
+// of the C++ *Descriptor objects, and fix up all circular references
+// within these objects.
+//
+// Note that the runtime performance of protocol message classes created in
+// this way is expected to be lousy.  The plan is to create an alternate
+// generator that outputs a Python/C extension module that lets
+// performance-minded Python code leverage the fast C++ implementation
+// directly.
+
+#include <utility>
+#include <map>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/compiler/python/python_generator.h>
+#include <google/protobuf/descriptor.pb.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace python {
+
+namespace {
+
+// Returns a copy of |filename| with any trailing ".protodevel" or ".proto
+// suffix stripped.
+// TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc.
+string StripProto(const string& filename) {
+  const char* suffix = HasSuffixString(filename, ".protodevel")
+      ? ".protodevel" : ".proto";
+  return StripSuffixString(filename, suffix);
+}
+
+
+// Returns the Python module name expected for a given .proto filename.
+string ModuleName(const string& filename) {
+  string basename = StripProto(filename);
+  StripString(&basename, "-", '_');
+  StripString(&basename, "/", '.');
+  return basename + "_pb2";
+}
+
+
+// Returns the name of all containing types for descriptor,
+// in order from outermost to innermost, followed by descriptor's
+// own name.  Each name is separated by |separator|.
+template <typename DescriptorT>
+string NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
+                                   const string& separator) {
+  string name = descriptor.name();
+  for (const Descriptor* current = descriptor.containing_type();
+       current != NULL; current = current->containing_type()) {
+    name = current->name() + separator + name;
+  }
+  return name;
+}
+
+
+// Name of the class attribute where we store the Python
+// descriptor.Descriptor instance for the generated class.
+// Must stay consistent with the _DESCRIPTOR_KEY constant
+// in proto2/public/reflection.py.
+const char kDescriptorKey[] = "DESCRIPTOR";
+
+
+// Prints the common boilerplate needed at the top of every .py
+// file output by this generator.
+void PrintTopBoilerplate(
+    io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) {
+  // TODO(robinson): Allow parameterization of Python version?
+  printer->Print(
+      "#!/usr/bin/python2.4\n"
+      "# Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
+      "\n"
+      "from google.protobuf import descriptor\n"
+      "from google.protobuf import message\n"
+      "from google.protobuf import reflection\n"
+      "from google.protobuf import service\n"
+      "from google.protobuf import service_reflection\n");
+  // Avoid circular imports if this module is descriptor_pb2.
+  if (!descriptor_proto) {
+    printer->Print(
+        "from google.protobuf import descriptor_pb2\n");
+  }
+}
+
+
+// Returns a Python literal giving the default value for a field.
+// If the field specifies no explicit default value, we'll return
+// the default default value for the field type (zero for numbers,
+// empty string for strings, empty list for repeated fields, and
+// None for non-repeated, composite fields).
+//
+// TODO(robinson): Unify with code from
+// //compiler/cpp/internal/primitive_field.cc
+// //compiler/cpp/internal/enum_field.cc
+// //compiler/cpp/internal/string_field.cc
+string StringifyDefaultValue(const FieldDescriptor& field) {
+  if (field.is_repeated()) {
+    return "[]";
+  }
+
+  switch (field.cpp_type()) {
+    case FieldDescriptor::CPPTYPE_INT32:
+      return SimpleItoa(field.default_value_int32());
+    case FieldDescriptor::CPPTYPE_UINT32:
+      return SimpleItoa(field.default_value_uint32());
+    case FieldDescriptor::CPPTYPE_INT64:
+      return SimpleItoa(field.default_value_int64());
+    case FieldDescriptor::CPPTYPE_UINT64:
+      return SimpleItoa(field.default_value_uint64());
+    case FieldDescriptor::CPPTYPE_DOUBLE:
+      return SimpleDtoa(field.default_value_double());
+    case FieldDescriptor::CPPTYPE_FLOAT:
+      return SimpleFtoa(field.default_value_float());
+    case FieldDescriptor::CPPTYPE_BOOL:
+      return field.default_value_bool() ? "True" : "False";
+    case FieldDescriptor::CPPTYPE_ENUM:
+      return SimpleItoa(field.default_value_enum()->number());
+    case FieldDescriptor::CPPTYPE_STRING:
+      return "\"" + CEscape(field.default_value_string()) + "\"";
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      return "None";
+  }
+  // (We could add a default case above but then we wouldn't get the nice
+  // compiler warning when a new type is added.)
+  GOOGLE_LOG(FATAL) << "Not reached.";
+  return "";
+}
+
+
+
+}  // namespace
+
+
+Generator::Generator() : file_(NULL) {
+}
+
+Generator::~Generator() {
+}
+
+bool Generator::Generate(const FileDescriptor* file,
+                         const string& parameter,
+                         OutputDirectory* output_directory,
+                         string* error) const {
+
+  // Completely serialize all Generate() calls on this instance.  The
+  // thread-safety constraints of the CodeGenerator interface aren't clear so
+  // just be as conservative as possible.  It's easier to relax this later if
+  // we need to, but I doubt it will be an issue.
+  // TODO(kenton):  The proper thing to do would be to allocate any state on
+  //   the stack and use that, so that the Generator class itself does not need
+  //   to have any mutable members.  Then it is implicitly thread-safe.
+  MutexLock lock(&mutex_);
+  file_ = file;
+  string module_name = ModuleName(file->name());
+  string filename = module_name;
+  StripString(&filename, ".", '/');
+  filename += ".py";
+
+
+  scoped_ptr<io::ZeroCopyOutputStream> output(output_directory->Open(filename));
+  GOOGLE_CHECK(output.get());
+  io::Printer printer(output.get(), '$');
+  printer_ = &printer;
+
+  PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
+  PrintTopLevelEnums();
+  PrintTopLevelExtensions();
+  PrintAllNestedEnumsInFile();
+  PrintMessageDescriptors();
+  // We have to print the imports after the descriptors, so that mutually
+  // recursive protos in separate files can successfully reference each other.
+  PrintImports();
+  FixForeignFieldsInDescriptors();
+  PrintMessages();
+  // We have to fix up the extensions after the message classes themselves,
+  // since they need to call static RegisterExtension() methods on these
+  // classes.
+  FixForeignFieldsInExtensions();
+  PrintServices();
+  return !printer.failed();
+}
+
+// Prints Python imports for all modules imported by |file|.
+void Generator::PrintImports() const {
+  for (int i = 0; i < file_->dependency_count(); ++i) {
+    string module_name = ModuleName(file_->dependency(i)->name());
+    printer_->Print("import $module$\n", "module",
+                    module_name);
+  }
+  printer_->Print("\n");
+}
+
+// Prints descriptors and module-level constants for all top-level
+// enums defined in |file|.
+void Generator::PrintTopLevelEnums() const {
+  vector<pair<string, int> > top_level_enum_values;
+  for (int i = 0; i < file_->enum_type_count(); ++i) {
+    const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
+    PrintEnum(enum_descriptor);
+    printer_->Print("\n");
+
+    for (int j = 0; j < enum_descriptor.value_count(); ++j) {
+      const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j);
+      top_level_enum_values.push_back(
+          make_pair(value_descriptor.name(), value_descriptor.number()));
+    }
+  }
+
+  for (int i = 0; i < top_level_enum_values.size(); ++i) {
+    printer_->Print("$name$ = $value$\n",
+                    "name", top_level_enum_values[i].first,
+                    "value", SimpleItoa(top_level_enum_values[i].second));
+  }
+  printer_->Print("\n");
+}
+
+// Prints all enums contained in all message types in |file|.
+void Generator::PrintAllNestedEnumsInFile() const {
+  for (int i = 0; i < file_->message_type_count(); ++i) {
+    PrintNestedEnums(*file_->message_type(i));
+  }
+}
+
+// Prints a Python statement assigning the appropriate module-level
+// enum name to a Python EnumDescriptor object equivalent to
+// enum_descriptor.
+void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
+  map<string, string> m;
+  m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor);
+  m["name"] = enum_descriptor.name();
+  m["full_name"] = enum_descriptor.full_name();
+  m["filename"] = enum_descriptor.name();
+  const char enum_descriptor_template[] =
+      "$descriptor_name$ = descriptor.EnumDescriptor(\n"
+      "  name='$name$',\n"
+      "  full_name='$full_name$',\n"
+      "  filename='$filename$',\n"
+      "  values=[\n";
+  string options_string;
+  enum_descriptor.options().SerializeToString(&options_string);
+  printer_->Print(m, enum_descriptor_template);
+  printer_->Indent();
+  printer_->Indent();
+  for (int i = 0; i < enum_descriptor.value_count(); ++i) {
+    PrintEnumValueDescriptor(*enum_descriptor.value(i));
+    printer_->Print(",\n");
+  }
+  printer_->Outdent();
+  printer_->Print("],\n");
+  printer_->Print("options=$options_value$,\n",
+                  "options_value",
+                  OptionsValue("EnumOptions", CEscape(options_string)));
+  printer_->Outdent();
+  printer_->Print(")\n");
+  printer_->Print("\n");
+}
+
+// Recursively prints enums in nested types within descriptor, then
+// prints enums contained at the top level in descriptor.
+void Generator::PrintNestedEnums(const Descriptor& descriptor) const {
+  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+    PrintNestedEnums(*descriptor.nested_type(i));
+  }
+
+  for (int i = 0; i < descriptor.enum_type_count(); ++i) {
+    PrintEnum(*descriptor.enum_type(i));
+  }
+}
+
+void Generator::PrintTopLevelExtensions() const {
+  const bool is_extension = true;
+  for (int i = 0; i < file_->extension_count(); ++i) {
+    const FieldDescriptor& extension_field = *file_->extension(i);
+    printer_->Print("$name$ = ", "name", extension_field.name());
+    PrintFieldDescriptor(extension_field, is_extension);
+    printer_->Print("\n");
+  }
+  printer_->Print("\n");
+}
+
+// Prints Python equivalents of all Descriptors in |file|.
+void Generator::PrintMessageDescriptors() const {
+  for (int i = 0; i < file_->message_type_count(); ++i) {
+    PrintDescriptor(*file_->message_type(i));
+    printer_->Print("\n");
+  }
+}
+
+void Generator::PrintServices() const {
+  for (int i = 0; i < file_->service_count(); ++i) {
+    PrintServiceDescriptor(*file_->service(i));
+    PrintServiceClass(*file_->service(i));
+    PrintServiceStub(*file_->service(i));
+    printer_->Print("\n");
+  }
+}
+
+void Generator::PrintServiceDescriptor(
+    const ServiceDescriptor& descriptor) const {
+  printer_->Print("\n");
+  string service_name = ModuleLevelServiceDescriptorName(descriptor);
+  string options_string;
+  descriptor.options().SerializeToString(&options_string);
+
+  printer_->Print(
+      "$service_name$ = descriptor.ServiceDescriptor(\n",
+      "service_name", service_name);
+  printer_->Indent();
+  map<string, string> m;
+  m["name"] = descriptor.name();
+  m["full_name"] = descriptor.full_name();
+  m["index"] = SimpleItoa(descriptor.index());
+  m["options_value"] = OptionsValue("ServiceOptions", options_string);
+  const char required_function_arguments[] =
+      "name='$name$',\n"
+      "full_name='$full_name$',\n"
+      "index=$index$,\n"
+      "options=$options_value$,\n"
+      "methods=[\n";
+  printer_->Print(m, required_function_arguments);
+  for (int i = 0; i < descriptor.method_count(); ++i) {
+    const MethodDescriptor* method = descriptor.method(i);
+    string options_string;
+    method->options().SerializeToString(&options_string);
+
+    m.clear();
+    m["name"] = method->name();
+    m["full_name"] = method->full_name();
+    m["index"] = SimpleItoa(method->index());
+    m["serialized_options"] = CEscape(options_string);
+    m["input_type"] = ModuleLevelDescriptorName(*(method->input_type()));
+    m["output_type"] = ModuleLevelDescriptorName(*(method->output_type()));
+    m["options_value"] = OptionsValue("MethodOptions", options_string);
+    printer_->Print("descriptor.MethodDescriptor(\n");
+    printer_->Indent();
+    printer_->Print(
+        m,
+        "name='$name$',\n"
+        "full_name='$full_name$',\n"
+        "index=$index$,\n"
+        "containing_service=None,\n"
+        "input_type=$input_type$,\n"
+        "output_type=$output_type$,\n"
+        "options=$options_value$,\n");
+    printer_->Outdent();
+    printer_->Print("),\n");
+  }
+
+  printer_->Outdent();
+  printer_->Print("])\n\n");
+}
+
+void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
+  // Print the service.
+  printer_->Print("class $class_name$(service.Service):\n",
+                  "class_name", descriptor.name());
+  printer_->Indent();
+  printer_->Print(
+      "__metaclass__ = service_reflection.GeneratedServiceType\n"
+      "$descriptor_key$ = $descriptor_name$\n",
+      "descriptor_key", kDescriptorKey,
+      "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
+  printer_->Outdent();
+}
+
+void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
+  // Print the service stub.
+  printer_->Print("class $class_name$_Stub($class_name$):\n",
+                  "class_name", descriptor.name());
+  printer_->Indent();
+  printer_->Print(
+      "__metaclass__ = service_reflection.GeneratedServiceStubType\n"
+      "$descriptor_key$ = $descriptor_name$\n",
+      "descriptor_key", kDescriptorKey,
+      "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
+  printer_->Outdent();
+}
+
+// Prints statement assigning ModuleLevelDescriptorName(message_descriptor)
+// to a Python Descriptor object for message_descriptor.
+//
+// Mutually recursive with PrintNestedDescriptors().
+void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
+  PrintNestedDescriptors(message_descriptor);
+
+  printer_->Print("\n");
+  printer_->Print("$descriptor_name$ = descriptor.Descriptor(\n",
+                  "descriptor_name",
+                  ModuleLevelDescriptorName(message_descriptor));
+  printer_->Indent();
+  map<string, string> m;
+  m["name"] = message_descriptor.name();
+  m["full_name"] = message_descriptor.full_name();
+  m["filename"] = message_descriptor.file()->name();
+  const char required_function_arguments[] =
+      "name='$name$',\n"
+      "full_name='$full_name$',\n"
+      "filename='$filename$',\n"
+      "containing_type=None,\n";  // TODO(robinson): Implement containing_type.
+  printer_->Print(m, required_function_arguments);
+  PrintFieldsInDescriptor(message_descriptor);
+  PrintExtensionsInDescriptor(message_descriptor);
+  // TODO(robinson): implement printing of nested_types.
+  printer_->Print("nested_types=[],  # TODO(robinson): Implement.\n");
+  printer_->Print("enum_types=[\n");
+  printer_->Indent();
+  for (int i = 0; i < message_descriptor.enum_type_count(); ++i) {
+    const string descriptor_name = ModuleLevelDescriptorName(
+        *message_descriptor.enum_type(i));
+    printer_->Print(descriptor_name.c_str());
+    printer_->Print(",\n");
+  }
+  printer_->Outdent();
+  printer_->Print("],\n");
+  string options_string;
+  message_descriptor.options().SerializeToString(&options_string);
+  printer_->Print(
+      "options=$options_value$",
+      "options_value", OptionsValue("MessageOptions", options_string));
+  printer_->Outdent();
+  printer_->Print(")\n");
+}
+
+// Prints Python Descriptor objects for all nested types contained in
+// message_descriptor.
+//
+// Mutually recursive with PrintDescriptor().
+void Generator::PrintNestedDescriptors(
+    const Descriptor& containing_descriptor) const {
+  for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
+    PrintDescriptor(*containing_descriptor.nested_type(i));
+  }
+}
+
+// Prints all messages in |file|.
+void Generator::PrintMessages() const {
+  for (int i = 0; i < file_->message_type_count(); ++i) {
+    PrintMessage(*file_->message_type(i));
+    printer_->Print("\n");
+  }
+}
+
+// Prints a Python class for the given message descriptor.  We defer to the
+// metaclass to do almost all of the work of actually creating a useful class.
+// The purpose of this function and its many helper functions above is merely
+// to output a Python version of the descriptors, which the metaclass in
+// reflection.py will use to construct the meat of the class itself.
+//
+// Mutually recursive with PrintNestedMessages().
+void Generator::PrintMessage(
+    const Descriptor& message_descriptor) const {
+  printer_->Print("class $name$(message.Message):\n", "name",
+                  message_descriptor.name());
+  printer_->Indent();
+  printer_->Print("__metaclass__ = reflection.GeneratedProtocolMessageType\n");
+  PrintNestedMessages(message_descriptor);
+  map<string, string> m;
+  m["descriptor_key"] = kDescriptorKey;
+  m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
+  printer_->Print(m, "$descriptor_key$ = $descriptor_name$\n");
+  printer_->Outdent();
+}
+
+// Prints all nested messages within |containing_descriptor|.
+// Mutually recursive with PrintMessage().
+void Generator::PrintNestedMessages(
+    const Descriptor& containing_descriptor) const {
+  for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
+    printer_->Print("\n");
+    PrintMessage(*containing_descriptor.nested_type(i));
+  }
+}
+
+// Recursively fixes foreign fields in all nested types in |descriptor|, then
+// sets the message_type and enum_type of all message and enum fields to point
+// to their respective descriptors.
+void Generator::FixForeignFieldsInDescriptor(
+    const Descriptor& descriptor) const {
+  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+    FixForeignFieldsInDescriptor(*descriptor.nested_type(i));
+  }
+
+  for (int i = 0; i < descriptor.field_count(); ++i) {
+    const FieldDescriptor& field_descriptor = *descriptor.field(i);
+    FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name");
+  }
+}
+
+// Sets any necessary message_type and enum_type attributes
+// for the Python version of |field|.
+//
+// containing_type may be NULL, in which case this is a module-level field.
+//
+// python_dict_name is the name of the Python dict where we should
+// look the field up in the containing type.  (e.g., fields_by_name
+// or extensions_by_name).  We ignore python_dict_name if containing_type
+// is NULL.
+void Generator::FixForeignFieldsInField(const Descriptor* containing_type,
+                                        const FieldDescriptor& field,
+                                        const string& python_dict_name) const {
+  const string field_referencing_expression = FieldReferencingExpression(
+      containing_type, field, python_dict_name);
+  map<string, string> m;
+  m["field_ref"] = field_referencing_expression;
+  const Descriptor* foreign_message_type = field.message_type();
+  if (foreign_message_type) {
+    m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type);
+    printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n");
+  }
+  const EnumDescriptor* enum_type = field.enum_type();
+  if (enum_type) {
+    m["enum_type"] = ModuleLevelDescriptorName(*enum_type);
+    printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n");
+  }
+}
+
+// Returns the module-level expression for the given FieldDescriptor.
+// Only works for fields in the .proto file this Generator is generating for.
+//
+// containing_type may be NULL, in which case this is a module-level field.
+//
+// python_dict_name is the name of the Python dict where we should
+// look the field up in the containing type.  (e.g., fields_by_name
+// or extensions_by_name).  We ignore python_dict_name if containing_type
+// is NULL.
+string Generator::FieldReferencingExpression(
+    const Descriptor* containing_type,
+    const FieldDescriptor& field,
+    const string& python_dict_name) const {
+  // We should only ever be looking up fields in the current file.
+  // The only things we refer to from other files are message descriptors.
+  GOOGLE_CHECK_EQ(field.file(), file_) << field.file()->name() << " vs. "
+                                << file_->name();
+  if (!containing_type) {
+    return field.name();
+  }
+  return strings::Substitute(
+      "$0.$1['$2']",
+      ModuleLevelDescriptorName(*containing_type),
+      python_dict_name, field.name());
+}
+
+// Prints statements setting the message_type and enum_type fields in the
+// Python descriptor objects we've already output in ths file.  We must
+// do this in a separate step due to circular references (otherwise, we'd
+// just set everything in the initial assignment statements).
+void Generator::FixForeignFieldsInDescriptors() const {
+  for (int i = 0; i < file_->message_type_count(); ++i) {
+    FixForeignFieldsInDescriptor(*file_->message_type(i));
+  }
+  printer_->Print("\n");
+}
+
+// We need to not only set any necessary message_type fields, but
+// also need to call RegisterExtension() on each message we're
+// extending.
+void Generator::FixForeignFieldsInExtensions() const {
+  // Top-level extensions.
+  for (int i = 0; i < file_->extension_count(); ++i) {
+    FixForeignFieldsInExtension(*file_->extension(i));
+  }
+  // Nested extensions.
+  for (int i = 0; i < file_->message_type_count(); ++i) {
+    FixForeignFieldsInNestedExtensions(*file_->message_type(i));
+  }
+}
+
+void Generator::FixForeignFieldsInExtension(
+    const FieldDescriptor& extension_field) const {
+  GOOGLE_CHECK(extension_field.is_extension());
+  // extension_scope() will be NULL for top-level extensions, which is
+  // exactly what FixForeignFieldsInField() wants.
+  FixForeignFieldsInField(extension_field.extension_scope(), extension_field,
+                          "extensions_by_name");
+
+  map<string, string> m;
+  // Confusingly, for FieldDescriptors that happen to be extensions,
+  // containing_type() means "extended type."
+  // On the other hand, extension_scope() will give us what we normally
+  // mean by containing_type().
+  m["extended_message_class"] = ModuleLevelMessageName(
+      *extension_field.containing_type());
+  m["field"] = FieldReferencingExpression(extension_field.extension_scope(),
+                                          extension_field,
+                                          "extensions_by_name");
+  printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n");
+}
+
+void Generator::FixForeignFieldsInNestedExtensions(
+    const Descriptor& descriptor) const {
+  // Recursively fix up extensions in all nested types.
+  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+    FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i));
+  }
+  // Fix up extensions directly contained within this type.
+  for (int i = 0; i < descriptor.extension_count(); ++i) {
+    FixForeignFieldsInExtension(*descriptor.extension(i));
+  }
+}
+
+// Returns a Python expression that instantiates a Python EnumValueDescriptor
+// object for the given C++ descriptor.
+void Generator::PrintEnumValueDescriptor(
+    const EnumValueDescriptor& descriptor) const {
+  // TODO(robinson): Fix up EnumValueDescriptor "type" fields.
+  // More circular references.  ::sigh::
+  string options_string;
+  descriptor.options().SerializeToString(&options_string);
+  map<string, string> m;
+  m["name"] = descriptor.name();
+  m["index"] = SimpleItoa(descriptor.index());
+  m["number"] = SimpleItoa(descriptor.number());
+  m["options"] = OptionsValue("EnumValueOptions", options_string);
+  printer_->Print(
+      m,
+      "descriptor.EnumValueDescriptor(\n"
+      "  name='$name$', index=$index$, number=$number$,\n"
+      "  options=$options$,\n"
+      "  type=None)");
+}
+
+string Generator::OptionsValue(
+    const string& class_name, const string& serialized_options) const {
+  if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
+    return "None";
+  } else {
+    string full_class_name = "descriptor_pb2." + class_name;
+    return "descriptor._ParseOptions(" + full_class_name + "(), '"
+        + CEscape(serialized_options)+ "')";
+  }
+}
+
+// Prints an expression for a Python FieldDescriptor for |field|.
+void Generator::PrintFieldDescriptor(
+    const FieldDescriptor& field, bool is_extension) const {
+  string options_string;
+  field.options().SerializeToString(&options_string);
+  map<string, string> m;
+  m["name"] = field.name();
+  m["full_name"] = field.full_name();
+  m["index"] = SimpleItoa(field.index());
+  m["number"] = SimpleItoa(field.number());
+  m["type"] = SimpleItoa(field.type());
+  m["cpp_type"] = SimpleItoa(field.cpp_type());
+  m["label"] = SimpleItoa(field.label());
+  m["default_value"] = StringifyDefaultValue(field);
+  m["is_extension"] = is_extension ? "True" : "False";
+  m["options"] = OptionsValue("FieldOptions", options_string);
+  // We always set message_type and enum_type to None at this point, and then
+  // these fields in correctly after all referenced descriptors have been
+  // defined and/or imported (see FixForeignFieldsInDescriptors()).
+  const char field_descriptor_decl[] =
+      "descriptor.FieldDescriptor(\n"
+      "  name='$name$', full_name='$full_name$', index=$index$,\n"
+      "  number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n"
+      "  default_value=$default_value$,\n"
+      "  message_type=None, enum_type=None, containing_type=None,\n"
+      "  is_extension=$is_extension$, extension_scope=None,\n"
+      "  options=$options$)";
+  printer_->Print(m, field_descriptor_decl);
+}
+
+// Helper for Print{Fields,Extensions}InDescriptor().
+void Generator::PrintFieldDescriptorsInDescriptor(
+    const Descriptor& message_descriptor,
+    bool is_extension,
+    const string& list_variable_name,
+    int (Descriptor::*CountFn)() const,
+    const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const {
+  printer_->Print("$list$=[\n", "list", list_variable_name);
+  printer_->Indent();
+  for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) {
+    PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i),
+                         is_extension);
+    printer_->Print(",\n");
+  }
+  printer_->Outdent();
+  printer_->Print("],\n");
+}
+
+// Prints a statement assigning "fields" to a list of Python FieldDescriptors,
+// one for each field present in message_descriptor.
+void Generator::PrintFieldsInDescriptor(
+    const Descriptor& message_descriptor) const {
+  const bool is_extension = false;
+  PrintFieldDescriptorsInDescriptor(
+      message_descriptor, is_extension, "fields",
+      &Descriptor::field_count, &Descriptor::field);
+}
+
+// Prints a statement assigning "extensions" to a list of Python
+// FieldDescriptors, one for each extension present in message_descriptor.
+void Generator::PrintExtensionsInDescriptor(
+    const Descriptor& message_descriptor) const {
+  const bool is_extension = true;
+  PrintFieldDescriptorsInDescriptor(
+      message_descriptor, is_extension, "extensions",
+      &Descriptor::extension_count, &Descriptor::extension);
+}
+
+bool Generator::GeneratingDescriptorProto() const {
+  return file_->name() == "google/protobuf/descriptor.proto";
+}
+
+// Returns the unique Python module-level identifier given to a descriptor.
+// This name is module-qualified iff the given descriptor describes an
+// entity that doesn't come from the current file.
+template <typename DescriptorT>
+string Generator::ModuleLevelDescriptorName(
+    const DescriptorT& descriptor) const {
+  // FIXME(robinson):
+  // We currently don't worry about collisions with underscores in the type
+  // names, so these would collide in nasty ways if found in the same file:
+  //   OuterProto.ProtoA.ProtoB
+  //   OuterProto_ProtoA.ProtoB  # Underscore instead of period.
+  // As would these:
+  //   OuterProto.ProtoA_.ProtoB
+  //   OuterProto.ProtoA._ProtoB  # Leading vs. trailing underscore.
+  // (Contrived, but certainly possible).
+  //
+  // The C++ implementation doesn't guard against this either.  Leaving
+  // it for now...
+  string name = NamePrefixedWithNestedTypes(descriptor, "_");
+  UpperString(&name);
+  // Module-private for now.  Easy to make public later; almost impossible
+  // to make private later.
+  name = "_" + name;
+  // We now have the name relative to its own module.  Also qualify with
+  // the module name iff this descriptor is from a different .proto file.
+  if (descriptor.file() != file_) {
+    name = ModuleName(descriptor.file()->name()) + "." + name;
+  }
+  return name;
+}
+
+// Returns the name of the message class itself, not the descriptor.
+// Like ModuleLevelDescriptorName(), module-qualifies the name iff
+// the given descriptor describes an entity that doesn't come from
+// the current file.
+string Generator::ModuleLevelMessageName(const Descriptor& descriptor) const {
+  string name = NamePrefixedWithNestedTypes(descriptor, ".");
+  if (descriptor.file() != file_) {
+    name = ModuleName(descriptor.file()->name()) + "." + name;
+  }
+  return name;
+}
+
+// Returns the unique Python module-level identifier given to a service
+// descriptor.
+string Generator::ModuleLevelServiceDescriptorName(
+    const ServiceDescriptor& descriptor) const {
+  string name = descriptor.name();
+  UpperString(&name);
+  name = "_" + name;
+  if (descriptor.file() != file_) {
+    name = ModuleName(descriptor.file()->name()) + "." + name;
+  }
+  return name;
+}
+
+}  // namespace python
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h
new file mode 100644
index 0000000..98ee0c6
--- /dev/null
+++ b/src/google/protobuf/compiler/python/python_generator.h
@@ -0,0 +1,129 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: robinson@google.com (Will Robinson)
+//
+// Generates Python code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
+
+#include <string>
+
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+class Descriptor;
+class EnumDescriptor;
+class EnumValueDescriptor;
+class FieldDescriptor;
+class ServiceDescriptor;
+
+namespace io { class Printer; }
+
+namespace compiler {
+namespace python {
+
+// CodeGenerator implementation for generated Python protocol buffer classes.
+// If you create your own protocol compiler binary and you want it to support
+// Python output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class LIBPROTOC_EXPORT Generator : public CodeGenerator {
+ public:
+  Generator();
+  virtual ~Generator();
+
+  // CodeGenerator methods.
+  virtual bool Generate(const FileDescriptor* file,
+                        const string& parameter,
+                        OutputDirectory* output_directory,
+                        string* error) const;
+
+ private:
+  void PrintImports() const;
+  void PrintTopLevelEnums() const;
+  void PrintAllNestedEnumsInFile() const;
+  void PrintNestedEnums(const Descriptor& descriptor) const;
+  void PrintEnum(const EnumDescriptor& enum_descriptor) const;
+
+  void PrintTopLevelExtensions() const;
+
+  void PrintFieldDescriptor(
+      const FieldDescriptor& field, bool is_extension) const;
+  void PrintFieldDescriptorsInDescriptor(
+      const Descriptor& message_descriptor,
+      bool is_extension,
+      const string& list_variable_name,
+      int (Descriptor::*CountFn)() const,
+      const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const;
+  void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const;
+  void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const;
+  void PrintMessageDescriptors() const;
+  void PrintDescriptor(const Descriptor& message_descriptor) const;
+  void PrintNestedDescriptors(const Descriptor& containing_descriptor) const;
+
+  void PrintMessages() const;
+  void PrintMessage(const Descriptor& message_descriptor) const;
+  void PrintNestedMessages(const Descriptor& containing_descriptor) const;
+
+  void FixForeignFieldsInDescriptors() const;
+  void FixForeignFieldsInDescriptor(const Descriptor& descriptor) const;
+  void FixForeignFieldsInField(const Descriptor* containing_type,
+                               const FieldDescriptor& field,
+                               const string& python_dict_name) const;
+  string FieldReferencingExpression(const Descriptor* containing_type,
+                                    const FieldDescriptor& field,
+                                    const string& python_dict_name) const;
+
+  void FixForeignFieldsInExtensions() const;
+  void FixForeignFieldsInExtension(
+      const FieldDescriptor& extension_field) const;
+  void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const;
+
+  void PrintServices() const;
+  void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const;
+  void PrintServiceClass(const ServiceDescriptor& descriptor) const;
+  void PrintServiceStub(const ServiceDescriptor& descriptor) const;
+
+  void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const;
+  string OptionsValue(const string& class_name,
+                      const string& serialized_options) const;
+  bool GeneratingDescriptorProto() const;
+
+  template <typename DescriptorT>
+  string ModuleLevelDescriptorName(const DescriptorT& descriptor) const;
+  string ModuleLevelMessageName(const Descriptor& descriptor) const;
+  string ModuleLevelServiceDescriptorName(
+      const ServiceDescriptor& descriptor) const;
+
+  // Very coarse-grained lock to ensure that Generate() is reentrant.
+  // Guards file_ and printer_.
+  mutable Mutex mutex_;
+  mutable const FileDescriptor* file_;  // Set in Generate().  Under mutex_.
+  mutable io::Printer* printer_;  // Set in Generate().  Under mutex_.
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
+};
+
+}  // namespace python
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
new file mode 100644
index 0000000..c75cf62
--- /dev/null
+++ b/src/google/protobuf/descriptor.cc
@@ -0,0 +1,2838 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/stubs/hash.h>
+#include <map>
+#include <set>
+#include <algorithm>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+#undef PACKAGE  // autoheader #defines this.  :(
+
+namespace google {
+namespace protobuf {
+
+const FieldDescriptor::CppType
+FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = {
+  static_cast<CppType>(0),  // 0 is reserved for errors
+
+  CPPTYPE_DOUBLE,   // TYPE_DOUBLE
+  CPPTYPE_FLOAT,    // TYPE_FLOAT
+  CPPTYPE_INT64,    // TYPE_INT64
+  CPPTYPE_UINT64,   // TYPE_UINT64
+  CPPTYPE_INT32,    // TYPE_INT32
+  CPPTYPE_UINT64,   // TYPE_FIXED64
+  CPPTYPE_UINT32,   // TYPE_FIXED32
+  CPPTYPE_BOOL,     // TYPE_BOOL
+  CPPTYPE_STRING,   // TYPE_STRING
+  CPPTYPE_MESSAGE,  // TYPE_GROUP
+  CPPTYPE_MESSAGE,  // TYPE_MESSAGE
+  CPPTYPE_STRING,   // TYPE_BYTES
+  CPPTYPE_UINT32,   // TYPE_UINT32
+  CPPTYPE_ENUM,     // TYPE_ENUM
+  CPPTYPE_INT32,    // TYPE_SFIXED32
+  CPPTYPE_INT64,    // TYPE_SFIXED64
+  CPPTYPE_INT32,    // TYPE_SINT32
+  CPPTYPE_INT64,    // TYPE_SINT64
+};
+
+const char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = {
+  "ERROR",     // 0 is reserved for errors
+
+  "double",    // TYPE_DOUBLE
+  "float",     // TYPE_FLOAT
+  "int64",     // TYPE_INT64
+  "uint64",    // TYPE_UINT64
+  "int32",     // TYPE_INT32
+  "fixed64",   // TYPE_FIXED64
+  "fixed32",   // TYPE_FIXED32
+  "bool",      // TYPE_BOOL
+  "string",    // TYPE_STRING
+  "group",     // TYPE_GROUP
+  "message",   // TYPE_MESSAGE
+  "bytes",     // TYPE_BYTES
+  "uint32",    // TYPE_UINT32
+  "enum",      // TYPE_ENUM
+  "sfixed32",  // TYPE_SFIXED32
+  "sfixed64",  // TYPE_SFIXED64
+  "sint32",    // TYPE_SINT32
+  "sint64",    // TYPE_SINT64
+};
+
+const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
+  "ERROR",     // 0 is reserved for errors
+
+  "optional",  // LABEL_OPTIONAL
+  "required",  // LABEL_REQUIRED
+  "repeated",  // LABEL_REPEATED
+};
+
+#ifndef _MSC_VER  // MSVC doesn't need these and won't even accept them.
+const int FieldDescriptor::kMaxNumber;
+const int FieldDescriptor::kFirstReservedNumber;
+const int FieldDescriptor::kLastReservedNumber;
+#endif
+
+namespace {
+
+const string kEmptyString;
+
+// A DescriptorPool contains a bunch of hash_maps to implement the
+// various Find*By*() methods.  Since hashtable lookups are O(1), it's
+// most efficient to construct a fixed set of large hash_maps used by
+// all objects in the pool rather than construct one or more small
+// hash_maps for each object.
+//
+// The keys to these hash_maps are (parent, name) or (parent, number)
+// pairs.  Unfortunately STL doesn't provide hash functions for pair<>,
+// so we must invent our own.
+//
+// TODO(kenton):  Use StringPiece rather than const char* in keys?  It would
+//   be a lot cleaner but we'd just have to convert it back to const char*
+//   for the open source release.
+
+typedef pair<const void*, const char*> PointerStringPair;
+
+// Used by GCC/SGI STL only.  (Why isn't this provided by the standard
+// library?  :( )
+struct CStringEqual {
+  inline bool operator()(const char* a, const char* b) const {
+    return strcmp(a, b) == 0;
+  }
+};
+
+struct PointerStringPairEqual {
+  inline bool operator()(const PointerStringPair& a,
+                         const PointerStringPair& b) const {
+    return a.first == b.first && strcmp(a.second, b.second) == 0;
+  }
+};
+
+template<typename PairType>
+struct PointerIntegerPairHash {
+  size_t operator()(const PairType& p) const {
+    // FIXME(kenton):  What is the best way to compute this hash?  I have
+    // no idea!  This seems a bit better than an XOR.
+    return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second;
+  }
+
+  // Used only by MSVC and platforms where hash_map is not available.
+  static const size_t bucket_size = 4;
+  static const size_t min_buckets = 8;
+  inline bool operator()(const PairType& a, const PairType& b) const {
+    return a.first < b.first ||
+          (a.first == b.first && a.second < b.second);
+  }
+};
+
+typedef pair<const Descriptor*, int> DescriptorIntPair;
+typedef pair<const EnumDescriptor*, int> EnumIntPair;
+
+struct PointerStringPairHash {
+  size_t operator()(const PointerStringPair& p) const {
+    // FIXME(kenton):  What is the best way to compute this hash?  I have
+    // no idea!  This seems a bit better than an XOR.
+    hash<const char*> cstring_hash;
+    return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) +
+           cstring_hash(p.second);
+  }
+
+  // Used only by MSVC and platforms where hash_map is not available.
+  static const size_t bucket_size = 4;
+  static const size_t min_buckets = 8;
+  inline bool operator()(const PointerStringPair& a,
+                         const PointerStringPair& b) const {
+    if (a.first < b.first) return true;
+    if (a.first > b.first) return false;
+    return strcmp(a.second, b.second) < 0;
+  }
+};
+
+
+struct Symbol {
+  enum Type {
+    NULL_SYMBOL, MESSAGE, FIELD, ENUM, ENUM_VALUE, SERVICE, METHOD, PACKAGE
+  };
+  Type type;
+  union {
+    const Descriptor* descriptor;
+    const FieldDescriptor* field_descriptor;
+    const EnumDescriptor* enum_descriptor;
+    const EnumValueDescriptor* enum_value_descriptor;
+    const ServiceDescriptor* service_descriptor;
+    const MethodDescriptor* method_descriptor;
+    const FileDescriptor* package_file_descriptor;
+  };
+
+  inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; }
+  inline bool IsNull() const { return type == NULL_SYMBOL; }
+
+#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD)  \
+  inline explicit Symbol(const TYPE* value) {    \
+    type = TYPE_CONSTANT;                        \
+    this->FIELD = value;                         \
+  }
+
+  CONSTRUCTOR(Descriptor         , MESSAGE   , descriptor             )
+  CONSTRUCTOR(FieldDescriptor    , FIELD     , field_descriptor       )
+  CONSTRUCTOR(EnumDescriptor     , ENUM      , enum_descriptor        )
+  CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor  )
+  CONSTRUCTOR(ServiceDescriptor  , SERVICE   , service_descriptor     )
+  CONSTRUCTOR(MethodDescriptor   , METHOD    , method_descriptor      )
+  CONSTRUCTOR(FileDescriptor     , PACKAGE   , package_file_descriptor)
+#undef CONSTRUCTOR
+
+  const FileDescriptor* GetFile() const {
+    switch (type) {
+      case NULL_SYMBOL: return NULL;
+      case MESSAGE    : return descriptor           ->file();
+      case FIELD      : return field_descriptor     ->file();
+      case ENUM       : return enum_descriptor      ->file();
+      case ENUM_VALUE : return enum_value_descriptor->type()->file();
+      case SERVICE    : return service_descriptor   ->file();
+      case METHOD     : return method_descriptor    ->service()->file();
+      case PACKAGE    : return package_file_descriptor;
+    }
+    return NULL;
+  }
+};
+
+const Symbol kNullSymbol;
+
+typedef hash_map<const char*, Symbol,
+                 hash<const char*>, CStringEqual>
+  SymbolsByNameMap;
+typedef hash_map<PointerStringPair, Symbol,
+                 PointerStringPairHash, PointerStringPairEqual>
+  SymbolsByParentMap;
+typedef hash_map<const char*, const FileDescriptor*,
+                 hash<const char*>, CStringEqual>
+  FilesByNameMap;
+typedef hash_map<DescriptorIntPair, const FieldDescriptor*,
+                 PointerIntegerPairHash<DescriptorIntPair> >
+  FieldsByNumberMap;
+typedef hash_map<EnumIntPair, const EnumValueDescriptor*,
+                 PointerIntegerPairHash<EnumIntPair> >
+  EnumValuesByNumberMap;
+
+}  // anonymous namespace
+
+// ===================================================================
+// DescriptorPool::Tables
+
+class DescriptorPool::Tables {
+ public:
+  Tables();
+  ~Tables();
+
+  // Checkpoint the state of the tables.  Future calls to Rollback() will
+  // return the Tables to this state.  This is used when building files, since
+  // some kinds of validation errors cannot be detected until the file's
+  // descriptors have already been added to the tables.  BuildFile() calls
+  // Checkpoint() before it starts building and Rollback() if it encounters
+  // an error.
+  void Checkpoint();
+
+  // Roll back the Tables to the state of the last Checkpoint(), removing
+  // everything that was added after that point.
+  void Rollback();
+
+  // The stack of files which are currently being built.  Used to detect
+  // cyclic dependencies when loading files from a DescriptorDatabase.  Not
+  // used when fallback_database_ == NULL.
+  vector<string> pending_files_;
+
+  // A set of files which we have tried to load from the fallback database
+  // and encountered errors.  We will not attempt to load them again.
+  // Not used when fallback_database_ == NULL.
+  hash_set<string> known_bad_files_;
+
+  // -----------------------------------------------------------------
+  // Finding items.
+
+  // Find symbols.  These return a null Symbol (symbol.IsNull() is true)
+  // if not found.  FindSymbolOfType() additionally returns null if the
+  // symbol is not of the given type.
+  inline Symbol FindSymbol(const string& key) const;
+  inline Symbol FindSymbolOfType(const string& key,
+                                 const Symbol::Type type) const;
+  inline Symbol FindNestedSymbol(const void* parent,
+                                 const string& name) const;
+  inline Symbol FindNestedSymbolOfType(const void* parent,
+                                       const string& name,
+                                       const Symbol::Type type) const;
+
+  // These return NULL if not found.
+  inline const FileDescriptor* FindFile(const string& key) const;
+  inline const FieldDescriptor* FindFieldByNumber(
+    const Descriptor* parent, int number) const;
+  inline const EnumValueDescriptor* FindEnumValueByNumber(
+    const EnumDescriptor* parent, int number) const;
+
+  // -----------------------------------------------------------------
+  // Adding items.
+
+  // These add items to the corresponding tables.  They return false if
+  // the key already exists in the table.  For AddSymbol(), the strings passed
+  // in must be ones that were constructed using AllocateString(), as they will
+  // be used as keys in the symbols_by_name_ and symbols_by_parent_ maps
+  // without copying.  (If parent is NULL, nothing is added to
+  // symbols_by_parent_.)
+  bool AddSymbol(const string& full_name,
+                 const void* parent, const string& name,
+                 Symbol symbol);
+  bool AddFile(const FileDescriptor* file);
+  bool AddFieldByNumber(const FieldDescriptor* field);
+  bool AddEnumValueByNumber(const EnumValueDescriptor* value);
+
+  // Like AddSymbol(), but only adds to symbols_by_parent_, not
+  // symbols_by_name_.  Used for enum values, which need to be registered
+  // under multiple parents (their type and its parent).
+  bool AddAliasUnderParent(const void* parent, const string& name,
+                           Symbol symbol);
+
+  // -----------------------------------------------------------------
+  // Allocating memory.
+
+  // Allocate an object which will be reclaimed when the pool is
+  // destroyed.  Note that the object's destructor will never be called,
+  // so its fields must be plain old data (primitive data types and
+  // pointers).  All of the descriptor types are such objects.
+  template<typename Type> Type* Allocate();
+
+  // Allocate an array of objects which will be reclaimed when the
+  // pool in destroyed.  Again, destructors are never called.
+  template<typename Type> Type* AllocateArray(int count);
+
+  // Allocate a string which will be destroyed when the pool is destroyed.
+  // The string is initialized to the given value for convenience.
+  string* AllocateString(const string& value);
+
+  // Allocate a protocol message object.
+  template<typename Type> Type* AllocateMessage();
+
+ private:
+  vector<string*> strings_;    // All strings in the pool.
+  vector<Message*> messages_;  // All messages in the pool.
+  vector<void*> allocations_;  // All other memory allocated in the pool.
+
+  SymbolsByNameMap      symbols_by_name_;
+  SymbolsByParentMap    symbols_by_parent_;
+  FilesByNameMap        files_by_name_;
+  FieldsByNumberMap     fields_by_number_;       // Includes extensions.
+  EnumValuesByNumberMap enum_values_by_number_;
+
+  int strings_before_checkpoint_;
+  int messages_before_checkpoint_;
+  int allocations_before_checkpoint_;
+  vector<const char*      > symbols_after_checkpoint_;
+  vector<PointerStringPair> symbols_by_parent_after_checkpoint_;
+  vector<const char*      > files_after_checkpoint_;
+  vector<DescriptorIntPair> field_numbers_after_checkpoint_;
+  vector<EnumIntPair      > enum_numbers_after_checkpoint_;
+
+  // Allocate some bytes which will be reclaimed when the pool is
+  // destroyed.
+  void* AllocateBytes(int size);
+};
+
+DescriptorPool::Tables::Tables()
+  : strings_before_checkpoint_(0),
+    messages_before_checkpoint_(0),
+    allocations_before_checkpoint_(0) {}
+
+DescriptorPool::Tables::~Tables() {
+  for (int i = 0; i < allocations_.size(); i++) {
+    operator delete(allocations_[i]);
+  }
+  STLDeleteElements(&strings_);
+  STLDeleteElements(&messages_);
+}
+
+void DescriptorPool::Tables::Checkpoint() {
+  strings_before_checkpoint_ = strings_.size();
+  messages_before_checkpoint_ = messages_.size();
+  allocations_before_checkpoint_ = allocations_.size();
+
+  symbols_after_checkpoint_.clear();
+  symbols_by_parent_after_checkpoint_.clear();
+  files_after_checkpoint_.clear();
+  field_numbers_after_checkpoint_.clear();
+  enum_numbers_after_checkpoint_.clear();
+}
+
+void DescriptorPool::Tables::Rollback() {
+  for (int i = 0; i < symbols_after_checkpoint_.size(); i++) {
+    symbols_by_name_.erase(symbols_after_checkpoint_[i]);
+  }
+  for (int i = 0; i < symbols_by_parent_after_checkpoint_.size(); i++) {
+    symbols_by_parent_.erase(symbols_by_parent_after_checkpoint_[i]);
+  }
+  for (int i = 0; i < files_after_checkpoint_.size(); i++) {
+    files_by_name_.erase(files_after_checkpoint_[i]);
+  }
+  for (int i = 0; i < field_numbers_after_checkpoint_.size(); i++) {
+    fields_by_number_.erase(field_numbers_after_checkpoint_[i]);
+  }
+  for (int i = 0; i < enum_numbers_after_checkpoint_.size(); i++) {
+    enum_values_by_number_.erase(enum_numbers_after_checkpoint_[i]);
+  }
+
+  symbols_after_checkpoint_.clear();
+  symbols_by_parent_after_checkpoint_.clear();
+  files_after_checkpoint_.clear();
+  field_numbers_after_checkpoint_.clear();
+  enum_numbers_after_checkpoint_.clear();
+
+  STLDeleteContainerPointers(
+    strings_.begin() + strings_before_checkpoint_, strings_.end());
+  STLDeleteContainerPointers(
+    messages_.begin() + messages_before_checkpoint_, messages_.end());
+  for (int i = allocations_before_checkpoint_; i < allocations_.size(); i++) {
+    operator delete(allocations_[i]);
+  }
+
+  strings_.resize(strings_before_checkpoint_);
+  messages_.resize(messages_before_checkpoint_);
+  allocations_.resize(allocations_before_checkpoint_);
+}
+
+// -------------------------------------------------------------------
+
+inline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const {
+  const Symbol* result = FindOrNull(symbols_by_name_, key.c_str());
+  if (result == NULL) {
+    return kNullSymbol;
+  } else {
+    return *result;
+  }
+}
+
+inline Symbol DescriptorPool::Tables::FindSymbolOfType(
+    const string& key, const Symbol::Type type) const {
+  Symbol result = FindSymbol(key);
+  if (result.type != type) return kNullSymbol;
+  return result;
+}
+
+inline Symbol DescriptorPool::Tables::FindNestedSymbol(
+    const void* parent, const string& name) const {
+  const Symbol* result =
+    FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str()));
+  if (result == NULL) {
+    return kNullSymbol;
+  } else {
+    return *result;
+  }
+}
+
+inline Symbol DescriptorPool::Tables::FindNestedSymbolOfType(
+    const void* parent, const string& name, const Symbol::Type type) const {
+  Symbol result = FindNestedSymbol(parent, name);
+  if (result.type != type) return kNullSymbol;
+  return result;
+}
+
+inline const FileDescriptor* DescriptorPool::Tables::FindFile(
+    const string& key) const {
+  return FindPtrOrNull(files_by_name_, key.c_str());
+}
+
+inline const FieldDescriptor* DescriptorPool::Tables::FindFieldByNumber(
+    const Descriptor* parent, int number) const {
+  return FindPtrOrNull(fields_by_number_, make_pair(parent, number));
+}
+
+inline const EnumValueDescriptor* DescriptorPool::Tables::FindEnumValueByNumber(
+    const EnumDescriptor* parent, int number) const {
+  return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number));
+}
+
+// -------------------------------------------------------------------
+
+bool DescriptorPool::Tables::AddSymbol(
+    const string& full_name,
+    const void* parent, const string& name,
+    Symbol symbol) {
+  if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) {
+    symbols_after_checkpoint_.push_back(full_name.c_str());
+
+    if (parent != NULL && !AddAliasUnderParent(parent, name, symbol)) {
+      GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in "
+                     "symbols_by_name_, but was defined in symbols_by_parent_; "
+                     "this shouldn't be possible.";
+      return false;
+    }
+
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool DescriptorPool::Tables::AddAliasUnderParent(
+    const void* parent, const string& name, Symbol symbol) {
+  PointerStringPair by_parent_key(parent, name.c_str());
+  if (InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol)) {
+    symbols_by_parent_after_checkpoint_.push_back(by_parent_key);
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) {
+  if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) {
+    files_after_checkpoint_.push_back(file->name().c_str());
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool DescriptorPool::Tables::AddFieldByNumber(const FieldDescriptor* field) {
+  DescriptorIntPair key(field->containing_type(), field->number());
+  if (InsertIfNotPresent(&fields_by_number_, key, field)) {
+    field_numbers_after_checkpoint_.push_back(key);
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool DescriptorPool::Tables::AddEnumValueByNumber(
+    const EnumValueDescriptor* value) {
+  EnumIntPair key(value->type(), value->number());
+  if (InsertIfNotPresent(&enum_values_by_number_, key, value)) {
+    enum_numbers_after_checkpoint_.push_back(key);
+    return true;
+  } else {
+    return false;
+  }
+}
+
+// -------------------------------------------------------------------
+
+template<typename Type>
+Type* DescriptorPool::Tables::Allocate() {
+  return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type)));
+}
+
+template<typename Type>
+Type* DescriptorPool::Tables::AllocateArray(int count) {
+  return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count));
+}
+
+string* DescriptorPool::Tables::AllocateString(const string& value) {
+  string* result = new string(value);
+  strings_.push_back(result);
+  return result;
+}
+
+template<typename Type>
+Type* DescriptorPool::Tables::AllocateMessage() {
+  Type* result = new Type;
+  messages_.push_back(result);
+  return result;
+}
+
+void* DescriptorPool::Tables::AllocateBytes(int size) {
+  // TODO(kenton):  Would it be worthwhile to implement this in some more
+  // sophisticated way?  Probably not for the open source release, but for
+  // internal use we could easily plug in one of our existing memory pool
+  // allocators...
+  if (size == 0) return NULL;
+
+  void* result = operator new(size);
+  allocations_.push_back(result);
+  return result;
+}
+
+// ===================================================================
+// DescriptorPool
+
+DescriptorPool::ErrorCollector::~ErrorCollector() {}
+
+DescriptorPool::DescriptorPool()
+  : mutex_(NULL),
+    fallback_database_(NULL),
+    default_error_collector_(NULL),
+    underlay_(NULL),
+    tables_(new Tables),
+    enforce_dependencies_(true),
+    last_internal_build_generated_file_call_(NULL) {}
+
+DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
+                               ErrorCollector* error_collector)
+  : mutex_(new Mutex),
+    fallback_database_(fallback_database),
+    default_error_collector_(error_collector),
+    underlay_(NULL),
+    tables_(new Tables),
+    enforce_dependencies_(true),
+    last_internal_build_generated_file_call_(NULL) {
+}
+
+DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
+  : mutex_(NULL),
+    fallback_database_(NULL),
+    default_error_collector_(NULL),
+    underlay_(underlay),
+    tables_(new Tables),
+    last_internal_build_generated_file_call_(NULL) {}
+
+DescriptorPool::~DescriptorPool() {
+  if (mutex_ != NULL) delete mutex_;
+}
+
+// DescriptorPool::BuildFile() defined later.
+// DescriptorPool::BuildFileCollectingErrors() defined later.
+// DescriptorPool::InternalBuildGeneratedFile() defined later.
+
+const DescriptorPool* DescriptorPool::generated_pool() {
+  return internal_generated_pool();
+}
+
+DescriptorPool* DescriptorPool::internal_generated_pool() {
+  static DescriptorPool singleton;
+  return &singleton;
+}
+
+void DescriptorPool::InternalDontEnforceDependencies() {
+  enforce_dependencies_ = false;
+}
+
+// Find*By* methods ==================================================
+
+// TODO(kenton):  There's a lot of repeated code here, but I'm not sure if
+//   there's any good way to factor it out.  Think about this some time when
+//   there's nothing more important to do (read: never).
+
+const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const {
+  MutexLockMaybe lock(mutex_);
+  const FileDescriptor* result = tables_->FindFile(name);
+  if (result != NULL) return result;
+  if (underlay_ != NULL) {
+    const FileDescriptor* result = underlay_->FindFileByName(name);
+    if (result != NULL) return result;
+  }
+  if (TryFindFileInFallbackDatabase(name)) {
+    const FileDescriptor* result = tables_->FindFile(name);
+    if (result != NULL) return result;
+  }
+  return NULL;
+}
+
+const FileDescriptor* DescriptorPool::FindFileContainingSymbol(
+    const string& symbol_name) const {
+  MutexLockMaybe lock(mutex_);
+  Symbol result = tables_->FindSymbol(symbol_name);
+  if (!result.IsNull()) return result.GetFile();
+  if (underlay_ != NULL) {
+    const FileDescriptor* result =
+      underlay_->FindFileContainingSymbol(symbol_name);
+    if (result != NULL) return result;
+  }
+  if (TryFindSymbolInFallbackDatabase(symbol_name)) {
+    Symbol result = tables_->FindSymbol(symbol_name);
+    if (!result.IsNull()) return result.GetFile();
+  }
+  return NULL;
+}
+
+const Descriptor* DescriptorPool::FindMessageTypeByName(
+    const string& name) const {
+  MutexLockMaybe lock(mutex_);
+  Symbol result = tables_->FindSymbolOfType(name, Symbol::MESSAGE);
+  if (!result.IsNull()) return result.descriptor;
+  if (underlay_ != NULL) {
+    const Descriptor* result = underlay_->FindMessageTypeByName(name);
+    if (result != NULL) return result;
+  }
+  if (TryFindSymbolInFallbackDatabase(name)) {
+    Symbol result = tables_->FindSymbolOfType(name, Symbol::MESSAGE);
+    if (!result.IsNull()) return result.descriptor;
+  }
+  return NULL;
+}
+
+const FieldDescriptor* DescriptorPool::FindFieldByName(
+    const string& name) const {
+  MutexLockMaybe lock(mutex_);
+  Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD);
+  if (!result.IsNull() && !result.field_descriptor->is_extension()) {
+    return result.field_descriptor;
+  }
+  if (underlay_ != NULL) {
+    const FieldDescriptor* result = underlay_->FindFieldByName(name);
+    if (result != NULL) return result;
+  }
+  if (TryFindSymbolInFallbackDatabase(name)) {
+    Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD);
+    if (!result.IsNull() && !result.field_descriptor->is_extension()) {
+      return result.field_descriptor;
+    }
+  }
+  return NULL;
+}
+
+const FieldDescriptor* DescriptorPool::FindExtensionByName(
+    const string& name) const {
+  MutexLockMaybe lock(mutex_);
+  Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD);
+  if (!result.IsNull() && result.field_descriptor->is_extension()) {
+    return result.field_descriptor;
+  }
+  if (underlay_ != NULL) {
+    const FieldDescriptor* result = underlay_->FindExtensionByName(name);
+    if (result != NULL) return result;
+  }
+  if (TryFindSymbolInFallbackDatabase(name)) {
+    Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD);
+    if (!result.IsNull() && result.field_descriptor->is_extension()) {
+      return result.field_descriptor;
+    }
+  }
+  return NULL;
+}
+
+const EnumDescriptor* DescriptorPool::FindEnumTypeByName(
+    const string& name) const {
+  MutexLockMaybe lock(mutex_);
+  Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM);
+  if (!result.IsNull()) return result.enum_descriptor;
+  if (underlay_ != NULL) {
+    const EnumDescriptor* result = underlay_->FindEnumTypeByName(name);
+    if (result != NULL) return result;
+  }
+  if (TryFindSymbolInFallbackDatabase(name)) {
+    Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM);
+    if (!result.IsNull()) return result.enum_descriptor;
+  }
+  return NULL;
+}
+
+const EnumValueDescriptor* DescriptorPool::FindEnumValueByName(
+    const string& name) const {
+  MutexLockMaybe lock(mutex_);
+  Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM_VALUE);
+  if (!result.IsNull()) return result.enum_value_descriptor;
+  if (underlay_ != NULL) {
+    const EnumValueDescriptor* result = underlay_->FindEnumValueByName(name);
+    if (result != NULL) return result;
+  }
+  if (TryFindSymbolInFallbackDatabase(name)) {
+    Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM_VALUE);
+    if (!result.IsNull()) return result.enum_value_descriptor;
+  }
+  return NULL;
+}
+
+const ServiceDescriptor* DescriptorPool::FindServiceByName(
+    const string& name) const {
+  MutexLockMaybe lock(mutex_);
+  Symbol result = tables_->FindSymbolOfType(name, Symbol::SERVICE);
+  if (!result.IsNull()) return result.service_descriptor;
+  if (underlay_ != NULL) {
+    const ServiceDescriptor* result = underlay_->FindServiceByName(name);
+    if (result != NULL) return result;
+  }
+  if (TryFindSymbolInFallbackDatabase(name)) {
+    Symbol result = tables_->FindSymbolOfType(name, Symbol::SERVICE);
+    if (!result.IsNull()) return result.service_descriptor;
+  }
+  return NULL;
+}
+
+const MethodDescriptor* DescriptorPool::FindMethodByName(
+    const string& name) const {
+  MutexLockMaybe lock(mutex_);
+  Symbol result = tables_->FindSymbolOfType(name, Symbol::METHOD);
+  if (!result.IsNull()) return result.method_descriptor;
+  if (underlay_ != NULL) {
+    const MethodDescriptor* result = underlay_->FindMethodByName(name);
+    if (result != NULL) return result;
+  }
+  if (TryFindSymbolInFallbackDatabase(name)) {
+    Symbol result = tables_->FindSymbolOfType(name, Symbol::METHOD);
+    if (!result.IsNull()) return result.method_descriptor;
+  }
+  return NULL;
+}
+
+const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
+    const Descriptor* extendee, int number) const {
+  MutexLockMaybe lock(mutex_);
+  const FieldDescriptor* result = tables_->FindFieldByNumber(extendee, number);
+  if (result != NULL && result->is_extension()) {
+    return result;
+  }
+  if (underlay_ != NULL) {
+    const FieldDescriptor* result =
+      underlay_->FindExtensionByNumber(extendee, number);
+    if (result != NULL) return result;
+  }
+  if (TryFindExtensionInFallbackDatabase(extendee, number)) {
+    const FieldDescriptor* result =
+      tables_->FindFieldByNumber(extendee, number);
+    if (result != NULL && result->is_extension()) {
+      return result;
+    }
+  }
+  return NULL;
+}
+
+// -------------------------------------------------------------------
+
+const FieldDescriptor*
+Descriptor::FindFieldByNumber(int key) const {
+  MutexLockMaybe lock(file()->pool()->mutex_);
+  const FieldDescriptor* result =
+    file()->pool()->tables_->FindFieldByNumber(this, key);
+  if (result == NULL || result->is_extension()) {
+    return NULL;
+  } else {
+    return result;
+  }
+}
+
+const FieldDescriptor*
+Descriptor::FindFieldByName(const string& key) const {
+  MutexLockMaybe lock(file()->pool()->mutex_);
+  Symbol result =
+    file()->pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
+  if (!result.IsNull() && !result.field_descriptor->is_extension()) {
+    return result.field_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const FieldDescriptor*
+Descriptor::FindExtensionByName(const string& key) const {
+  MutexLockMaybe lock(file()->pool()->mutex_);
+  Symbol result =
+    file()->pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
+  if (!result.IsNull() && result.field_descriptor->is_extension()) {
+    return result.field_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const Descriptor*
+Descriptor::FindNestedTypeByName(const string& key) const {
+  MutexLockMaybe lock(file()->pool()->mutex_);
+  Symbol result =
+    file()->pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE);
+  if (!result.IsNull()) {
+    return result.descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const EnumDescriptor*
+Descriptor::FindEnumTypeByName(const string& key) const {
+  MutexLockMaybe lock(file()->pool()->mutex_);
+  Symbol result =
+    file()->pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM);
+  if (!result.IsNull()) {
+    return result.enum_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const EnumValueDescriptor*
+Descriptor::FindEnumValueByName(const string& key) const {
+  MutexLockMaybe lock(file()->pool()->mutex_);
+  Symbol result =
+    file()->pool()->tables_->FindNestedSymbolOfType(
+      this, key, Symbol::ENUM_VALUE);
+  if (!result.IsNull()) {
+    return result.enum_value_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const EnumValueDescriptor*
+EnumDescriptor::FindValueByName(const string& key) const {
+  MutexLockMaybe lock(file()->pool()->mutex_);
+  Symbol result =
+    file()->pool()->tables_->FindNestedSymbolOfType(
+      this, key, Symbol::ENUM_VALUE);
+  if (!result.IsNull()) {
+    return result.enum_value_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const EnumValueDescriptor*
+EnumDescriptor::FindValueByNumber(int key) const {
+  MutexLockMaybe lock(file()->pool()->mutex_);
+  return file()->pool()->tables_->FindEnumValueByNumber(this, key);
+}
+
+const MethodDescriptor*
+ServiceDescriptor::FindMethodByName(const string& key) const {
+  MutexLockMaybe lock(file()->pool()->mutex_);
+  Symbol result =
+    file()->pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD);
+  if (!result.IsNull()) {
+    return result.method_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const Descriptor*
+FileDescriptor::FindMessageTypeByName(const string& key) const {
+  MutexLockMaybe lock(pool()->mutex_);
+  Symbol result =
+    pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE);
+  if (!result.IsNull()) {
+    return result.descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const EnumDescriptor*
+FileDescriptor::FindEnumTypeByName(const string& key) const {
+  MutexLockMaybe lock(pool()->mutex_);
+  Symbol result =
+    pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM);
+  if (!result.IsNull()) {
+    return result.enum_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const EnumValueDescriptor*
+FileDescriptor::FindEnumValueByName(const string& key) const {
+  MutexLockMaybe lock(pool()->mutex_);
+  Symbol result =
+    pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE);
+  if (!result.IsNull()) {
+    return result.enum_value_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const ServiceDescriptor*
+FileDescriptor::FindServiceByName(const string& key) const {
+  MutexLockMaybe lock(pool()->mutex_);
+  Symbol result =
+    pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE);
+  if (!result.IsNull()) {
+    return result.service_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const FieldDescriptor*
+FileDescriptor::FindExtensionByName(const string& key) const {
+  MutexLockMaybe lock(pool()->mutex_);
+  Symbol result =
+    pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
+  if (!result.IsNull() && result.field_descriptor->is_extension()) {
+    return result.field_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+bool Descriptor::IsExtensionNumber(int number) const {
+  // Linear search should be fine because we don't expect a message to have
+  // more than a couple extension ranges.
+  for (int i = 0; i < extension_range_count(); i++) {
+    if (number >= extension_range(i)->start &&
+        number <  extension_range(i)->end) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// -------------------------------------------------------------------
+
+bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const {
+  if (fallback_database_ == NULL) return false;
+
+  if (tables_->known_bad_files_.count(name) > 0) return false;
+
+  FileDescriptorProto file_proto;
+  if (!fallback_database_->FindFileByName(name, &file_proto) ||
+      BuildFileFromDatabase(file_proto) == NULL) {
+    tables_->known_bad_files_.insert(name);
+    return false;
+  }
+
+  return true;
+}
+
+bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const {
+  if (fallback_database_ == NULL) return false;
+
+  FileDescriptorProto file_proto;
+  if (!fallback_database_->FindFileContainingSymbol(name, &file_proto)) {
+    return false;
+  }
+
+  if (tables_->FindFile(file_proto.name()) != NULL) {
+    // We've already loaded this file, and it apparently doesn't contain the
+    // symbol we're looking for.  Some DescriptorDatabases return false
+    // positives.
+    return false;
+  }
+
+  if (BuildFileFromDatabase(file_proto) == NULL) {
+    return false;
+  }
+
+  return true;
+}
+
+bool DescriptorPool::TryFindExtensionInFallbackDatabase(
+    const Descriptor* containing_type, int field_number) const {
+  if (fallback_database_ == NULL) return false;
+
+  FileDescriptorProto file_proto;
+  if (!fallback_database_->FindFileContainingExtension(
+        containing_type->full_name(), field_number, &file_proto)) {
+    return false;
+  }
+
+  if (tables_->FindFile(file_proto.name()) != NULL) {
+    // We've already loaded this file, and it apparently doesn't contain the
+    // extension we're looking for.  Some DescriptorDatabases return false
+    // positives.
+    return false;
+  }
+
+  if (BuildFileFromDatabase(file_proto) == NULL) {
+    return false;
+  }
+
+  return true;
+}
+
+// ===================================================================
+
+string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const {
+  GOOGLE_CHECK(has_default_value()) << "No default value";
+  switch (cpp_type()) {
+    case CPPTYPE_INT32:
+      return SimpleItoa(default_value_int32());
+      break;
+    case CPPTYPE_INT64:
+      return SimpleItoa(default_value_int64());
+      break;
+    case CPPTYPE_UINT32:
+      return SimpleItoa(default_value_uint32());
+      break;
+    case CPPTYPE_UINT64:
+      return SimpleItoa(default_value_uint64());
+      break;
+    case CPPTYPE_FLOAT:
+      return SimpleFtoa(default_value_float());
+      break;
+    case CPPTYPE_DOUBLE:
+      return SimpleDtoa(default_value_double());
+      break;
+    case CPPTYPE_BOOL:
+      return default_value_bool() ? "true" : "false";
+      break;
+    case CPPTYPE_STRING:
+      if (quote_string_type) {
+        return "\"" + CEscape(default_value_string()) + "\"";
+      } else {
+        if (type() == TYPE_BYTES) {
+          return CEscape(default_value_string());
+        } else {
+          return default_value_string();
+        }
+      }
+      break;
+    case CPPTYPE_ENUM:
+      return default_value_enum()->name();
+      break;
+    case CPPTYPE_MESSAGE:
+      GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
+      break;
+  }
+  GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string";
+  return "";
+}
+
+// CopyTo methods ====================================================
+
+void FileDescriptor::CopyTo(FileDescriptorProto* proto) const {
+  proto->set_name(name());
+  if (!package().empty()) proto->set_package(package());
+
+  for (int i = 0; i < dependency_count(); i++) {
+    proto->add_dependency(dependency(i)->name());
+  }
+
+  for (int i = 0; i < message_type_count(); i++) {
+    message_type(i)->CopyTo(proto->add_message_type());
+  }
+  for (int i = 0; i < enum_type_count(); i++) {
+    enum_type(i)->CopyTo(proto->add_enum_type());
+  }
+  for (int i = 0; i < service_count(); i++) {
+    service(i)->CopyTo(proto->add_service());
+  }
+  for (int i = 0; i < extension_count(); i++) {
+    extension(i)->CopyTo(proto->add_extension());
+  }
+
+  if (&options() != &FileOptions::default_instance()) {
+    proto->mutable_options()->CopyFrom(options());
+  }
+}
+
+void Descriptor::CopyTo(DescriptorProto* proto) const {
+  proto->set_name(name());
+
+  for (int i = 0; i < field_count(); i++) {
+    field(i)->CopyTo(proto->add_field());
+  }
+  for (int i = 0; i < nested_type_count(); i++) {
+    nested_type(i)->CopyTo(proto->add_nested_type());
+  }
+  for (int i = 0; i < enum_type_count(); i++) {
+    enum_type(i)->CopyTo(proto->add_enum_type());
+  }
+  for (int i = 0; i < extension_range_count(); i++) {
+    DescriptorProto::ExtensionRange* range = proto->add_extension_range();
+    range->set_start(extension_range(i)->start);
+    range->set_end(extension_range(i)->end);
+  }
+  for (int i = 0; i < extension_count(); i++) {
+    extension(i)->CopyTo(proto->add_extension());
+  }
+
+  if (&options() != &MessageOptions::default_instance()) {
+    proto->mutable_options()->CopyFrom(options());
+  }
+}
+
+void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const {
+  proto->set_name(name());
+  proto->set_number(number());
+  proto->set_label(static_cast<FieldDescriptorProto::Label>(label()));
+  proto->set_type(static_cast<FieldDescriptorProto::Type>(type()));
+
+  if (is_extension()) {
+    proto->set_extendee(".");
+    proto->mutable_extendee()->append(containing_type()->full_name());
+  }
+
+  if (cpp_type() == CPPTYPE_MESSAGE) {
+    proto->set_type_name(".");
+    proto->mutable_type_name()->append(message_type()->full_name());
+  } else if (cpp_type() == CPPTYPE_ENUM) {
+    proto->set_type_name(".");
+    proto->mutable_type_name()->append(enum_type()->full_name());
+  }
+
+  if (has_default_value()) {
+    proto->set_default_value(DefaultValueAsString(false));
+  }
+
+  if (&options() != &FieldOptions::default_instance()) {
+    proto->mutable_options()->CopyFrom(options());
+  }
+}
+
+void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const {
+  proto->set_name(name());
+
+  for (int i = 0; i < value_count(); i++) {
+    value(i)->CopyTo(proto->add_value());
+  }
+
+  if (&options() != &EnumOptions::default_instance()) {
+    proto->mutable_options()->CopyFrom(options());
+  }
+}
+
+void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const {
+  proto->set_name(name());
+  proto->set_number(number());
+
+  if (&options() != &EnumValueOptions::default_instance()) {
+    proto->mutable_options()->CopyFrom(options());
+  }
+}
+
+void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const {
+  proto->set_name(name());
+
+  for (int i = 0; i < method_count(); i++) {
+    method(i)->CopyTo(proto->add_method());
+  }
+
+  if (&options() != &ServiceOptions::default_instance()) {
+    proto->mutable_options()->CopyFrom(options());
+  }
+}
+
+void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const {
+  proto->set_name(name());
+
+  proto->set_input_type(".");
+  proto->mutable_input_type()->append(input_type()->full_name());
+  proto->set_output_type(".");
+  proto->mutable_output_type()->append(output_type()->full_name());
+
+  if (&options() != &MethodOptions::default_instance()) {
+    proto->mutable_options()->CopyFrom(options());
+  }
+}
+
+// DebugString methods ===============================================
+
+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();
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(&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) {
+      continue;
+    }
+    int count = 1;
+    bool repeated = false;
+    if (fields[i]->is_repeated()) {
+      count = reflection->FieldSize(fields[i]);
+      repeated = true;
+    }
+    for (int j = 0; j < count; j++) {
+      string fieldval;
+      TextFormat::PrintFieldValueToString(options, fields[i],
+                                          repeated ? count : -1, &fieldval);
+      option_entries->push_back(fields[i]->name() + " = " + fieldval);
+    }
+  }
+  return !option_entries->empty();
+}
+
+// Formats options that all appear together in brackets. Does not include
+// brackets.
+bool FormatBracketedOptions(const Message &options, string *output) {
+  vector<string> all_options;
+  if (RetrieveOptions(options, &all_options)) {
+    output->append(JoinStrings(all_options, ", "));
+  }
+  return !all_options.empty();
+}
+
+// Formats options one per line
+bool FormatLineOptions(int depth, const Message &options, string *output) {
+  string prefix(depth * 2, ' ');
+  vector<string> all_options;
+  if (RetrieveOptions(options, &all_options)) {
+    for (int i = 0; i < all_options.size(); i++) {
+      strings::SubstituteAndAppend(output, "$0option $1;\n",
+                                   prefix, all_options[i]);
+    }
+  }
+  return !all_options.empty();
+}
+
+}  // anonymous namespace
+
+string FileDescriptor::DebugString() const {
+  string contents = "syntax = \"proto2\";\n\n";
+
+  for (int i = 0; i < dependency_count(); i++) {
+    strings::SubstituteAndAppend(&contents, "import \"$0\";\n",
+                                 dependency(i)->name());
+  }
+
+  if (!package().empty()) {
+    strings::SubstituteAndAppend(&contents, "package $0;\n\n", package());
+  }
+
+  if (FormatLineOptions(0, options(), &contents)) {
+    contents.append("\n");  // add some space if we had options
+  }
+
+  for (int i = 0; i < enum_type_count(); i++) {
+    enum_type(i)->DebugString(0, &contents);
+    contents.append("\n");
+  }
+
+  // Find all the 'group' type extensions; we will not output their nested
+  // definitions (those will be done with their group field descriptor).
+  set<const Descriptor*> groups;
+  for (int i = 0; i < extension_count(); i++) {
+    if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) {
+      groups.insert(extension(i)->message_type());
+    }
+  }
+
+  for (int i = 0; i < message_type_count(); i++) {
+    if (groups.count(message_type(i)) == 0) {
+      strings::SubstituteAndAppend(&contents, "message $0",
+                                   message_type(i)->name());
+      message_type(i)->DebugString(0, &contents);
+      contents.append("\n");
+    }
+  }
+
+  for (int i = 0; i < service_count(); i++) {
+    service(i)->DebugString(&contents);
+    contents.append("\n");
+  }
+
+  const Descriptor* containing_type = NULL;
+  for (int i = 0; i < extension_count(); i++) {
+    if (extension(i)->containing_type() != containing_type) {
+      if (i > 0) contents.append("}\n\n");
+      containing_type = extension(i)->containing_type();
+      strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
+                                   containing_type->full_name());
+    }
+    extension(i)->DebugString(1, &contents);
+  }
+  if (extension_count() > 0) contents.append("}\n\n");
+
+  return contents;
+}
+
+string Descriptor::DebugString() const {
+  string contents;
+  strings::SubstituteAndAppend(&contents, "message $0", name());
+  DebugString(0, &contents);
+  return contents;
+}
+
+void Descriptor::DebugString(int depth, string *contents) const {
+  string prefix(depth * 2, ' ');
+  ++depth;
+  contents->append(" {\n");
+
+  FormatLineOptions(depth, options(), contents);
+
+  // Find all the 'group' types for fields and extensions; we will not output
+  // their nested definitions (those will be done with their group field
+  // descriptor).
+  set<const Descriptor*> groups;
+  for (int i = 0; i < field_count(); i++) {
+    if (field(i)->type() == FieldDescriptor::TYPE_GROUP) {
+      groups.insert(field(i)->message_type());
+    }
+  }
+  for (int i = 0; i < extension_count(); i++) {
+    if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) {
+      groups.insert(extension(i)->message_type());
+    }
+  }
+
+  for (int i = 0; i < nested_type_count(); i++) {
+    if (groups.count(nested_type(i)) == 0) {
+      strings::SubstituteAndAppend(contents, "$0  message $1",
+                                   prefix, nested_type(i)->name());
+      nested_type(i)->DebugString(depth, contents);
+    }
+  }
+  for (int i = 0; i < enum_type_count(); i++) {
+    enum_type(i)->DebugString(depth, contents);
+  }
+  for (int i = 0; i < field_count(); i++) {
+    field(i)->DebugString(depth, contents);
+  }
+
+  for (int i = 0; i < extension_range_count(); i++) {
+    strings::SubstituteAndAppend(contents, "$0  extensions $1 to $2;\n",
+                                 prefix,
+                                 extension_range(i)->start,
+                                 extension_range(i)->end - 1);
+  }
+
+  // Group extensions by what they extend, so they can be printed out together.
+  const Descriptor* containing_type = NULL;
+  for (int i = 0; i < extension_count(); i++) {
+    if (extension(i)->containing_type() != containing_type) {
+      if (i > 0) strings::SubstituteAndAppend(contents, "$0  }\n", prefix);
+      containing_type = extension(i)->containing_type();
+      strings::SubstituteAndAppend(contents, "$0  extend .$1 {\n",
+                                   prefix, containing_type->full_name());
+    }
+    extension(i)->DebugString(depth + 1, contents);
+  }
+  if (extension_count() > 0)
+    strings::SubstituteAndAppend(contents, "$0  }\n", prefix);
+
+  strings::SubstituteAndAppend(contents, "$0}\n", prefix);
+}
+
+string FieldDescriptor::DebugString() const {
+  string contents;
+  int depth = 0;
+  if (is_extension()) {
+    strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
+                                 containing_type()->full_name());
+    depth = 1;
+  }
+  DebugString(depth, &contents);
+  if (is_extension()) {
+     contents.append("}\n");
+  }
+  return contents;
+}
+
+void FieldDescriptor::DebugString(int depth, string *contents) const {
+  string prefix(depth * 2, ' ');
+  string field_type;
+  switch (type()) {
+    case TYPE_MESSAGE:
+      field_type = "." + message_type()->full_name();
+      break;
+    case TYPE_ENUM:
+      field_type = "." + enum_type()->full_name();
+      break;
+    default:
+      field_type = kTypeToName[type()];
+  }
+
+  strings::SubstituteAndAppend(contents, "$0$1 $2 $3 = $4",
+                               prefix,
+                               kLabelToName[label()],
+                               field_type,
+                               type() == TYPE_GROUP ? message_type()->name() :
+                                                      name(),
+                               number());
+
+  bool bracketed = false;
+  if (has_default_value()) {
+    bracketed = true;
+    strings::SubstituteAndAppend(contents, " [default = $0",
+                                 DefaultValueAsString(true));
+  }
+
+  string formatted_options;
+  if (FormatBracketedOptions(options(), &formatted_options)) {
+    contents->append(bracketed ? ", " : " [");
+    bracketed = true;
+    contents->append(formatted_options);
+  }
+
+  if (bracketed) {
+    contents->append("]");
+  }
+
+  if (type() == TYPE_GROUP) {
+    message_type()->DebugString(depth, contents);
+  } else {
+    contents->append(";\n");
+  }
+}
+
+string EnumDescriptor::DebugString() const {
+  string contents;
+  DebugString(0, &contents);
+  return contents;
+}
+
+void EnumDescriptor::DebugString(int depth, string *contents) const {
+  string prefix(depth * 2, ' ');
+  ++depth;
+  strings::SubstituteAndAppend(contents, "$0enum $1 {\n",
+                               prefix, name());
+
+  FormatLineOptions(depth, options(), contents);
+
+  for (int i = 0; i < value_count(); i++) {
+    value(i)->DebugString(depth, contents);
+  }
+  strings::SubstituteAndAppend(contents, "$0}\n", prefix);
+}
+
+string EnumValueDescriptor::DebugString() const {
+  string contents;
+  DebugString(0, &contents);
+  return contents;
+}
+
+void EnumValueDescriptor::DebugString(int depth, string *contents) const {
+  string prefix(depth * 2, ' ');
+  strings::SubstituteAndAppend(contents, "$0$1 = $2",
+                               prefix, name(), number());
+
+  string formatted_options;
+  if (FormatBracketedOptions(options(), &formatted_options)) {
+    strings::SubstituteAndAppend(contents, " [$0]", formatted_options);
+  }
+  contents->append(";\n");
+}
+
+string ServiceDescriptor::DebugString() const {
+  string contents;
+  DebugString(&contents);
+  return contents;
+}
+
+void ServiceDescriptor::DebugString(string *contents) const {
+  strings::SubstituteAndAppend(contents, "service $0 {\n", name());
+
+  FormatLineOptions(1, options(), contents);
+
+  for (int i = 0; i < method_count(); i++) {
+    method(i)->DebugString(1, contents);
+  }
+
+  contents->append("}\n");
+}
+
+string MethodDescriptor::DebugString() const {
+  string contents;
+  DebugString(0, &contents);
+  return contents;
+}
+
+void MethodDescriptor::DebugString(int depth, string *contents) const {
+  string prefix(depth * 2, ' ');
+  ++depth;
+  strings::SubstituteAndAppend(contents, "$0rpc $1(.$2) returns (.$3)",
+                               prefix, name(),
+                               input_type()->full_name(),
+                               output_type()->full_name());
+
+  string formatted_options;
+  if (FormatLineOptions(depth, options(), &formatted_options)) {
+    strings::SubstituteAndAppend(contents, " {\n$0$1}\n",
+                                 formatted_options, prefix);
+  } else {
+    contents->append(";\n");
+  }
+}
+// ===================================================================
+
+class DescriptorBuilder {
+ public:
+  DescriptorBuilder(const DescriptorPool* pool,
+                    DescriptorPool::Tables* tables,
+                    DescriptorPool::ErrorCollector* error_collector);
+  ~DescriptorBuilder();
+
+  const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
+
+ private:
+  const DescriptorPool* pool_;
+  DescriptorPool::Tables* tables_;  // for convenience
+  DescriptorPool::ErrorCollector* error_collector_;
+  bool had_errors_;
+  string filename_;
+  FileDescriptor* file_;
+
+  // If LookupSymbol() finds a symbol that is in a file which is not a declared
+  // dependency of this file, it will fail, but will set
+  // possible_undeclared_dependency_ to point at that file.  This is only used
+  // by AddNotDefinedError() to report a more useful error message.
+  const FileDescriptor* possible_undeclared_dependency_;
+
+  void AddError(const string& element_name,
+                const Message& descriptor,
+                DescriptorPool::ErrorCollector::ErrorLocation location,
+                const string& error);
+
+  // Adds an error indicating that undefined_symbol was not defined.  Must
+  // only be called after LookupSymbol() fails.
+  void AddNotDefinedError(
+    const string& element_name,
+    const Message& descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location,
+    const string& undefined_symbol);
+
+  // Silly helper which determines if the given file is in the given package.
+  // I.e., either file->package() == package_name or file->package() is a
+  // nested package within package_name.
+  bool IsInPackage(const FileDescriptor* file, const string& package_name);
+
+  // Like tables_->FindSymbol(), but additionally:
+  // - Search the pool's underlay if not found in tables_.
+  // - Insure that the resulting Symbol is from one of the file's declared
+  //   dependencies.
+  Symbol FindSymbol(const string& name);
+
+  // Like FindSymbol(), but looks up the name relative to some other symbol
+  // name.  This first searches syblings of relative_to, then siblings of its
+  // parents, etc.  For example, LookupSymbol("foo.bar", "baz.qux.corge") makes
+  // the following calls, returning the first non-null result:
+  // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"),
+  // FindSymbol("foo.bar").
+  Symbol LookupSymbol(const string& name, const string& relative_to);
+
+  // Calls tables_->AddSymbol() and records an error if it fails.
+  void AddSymbol(const string& full_name,
+                 const void* parent, const string& name,
+                 const Message& proto, Symbol symbol);
+
+  // Like AddSymbol(), but succeeds if the symbol is already defined as long
+  // as the existing definition is also a package (because it's OK to define
+  // the same package in two different files).  Also adds all parents of the
+  // packgae to the symbol table (e.g. AddPackage("foo.bar", ...) will add
+  // "foo.bar" and "foo" to the table).
+  void AddPackage(const string& name, const Message& proto,
+                  const FileDescriptor* file);
+
+  // Checks that the symbol name contains only alphanumeric characters and
+  // underscores.  Records an error otherwise.
+  void ValidateSymbolName(const string& name, const string& full_name,
+                          const Message& proto);
+
+  // Used by BUILD_ARRAY macro (below) to avoid having to have the type
+  // specified as a macro parameter.
+  template <typename Type>
+  inline void AllocateArray(int size, Type** output) {
+    *output = tables_->AllocateArray<Type>(size);
+  }
+
+  // These methods all have the same signature for the sake of the BUILD_ARRAY
+  // macro, below.
+  void BuildMessage(const DescriptorProto& proto,
+                    const Descriptor* parent,
+                    Descriptor* result);
+  void BuildFieldOrExtension(const FieldDescriptorProto& proto,
+                             const Descriptor* parent,
+                             FieldDescriptor* result,
+                             bool is_extension);
+  void BuildField(const FieldDescriptorProto& proto,
+                  const Descriptor* parent,
+                  FieldDescriptor* result) {
+    BuildFieldOrExtension(proto, parent, result, false);
+  }
+  void BuildExtension(const FieldDescriptorProto& proto,
+                      const Descriptor* parent,
+                      FieldDescriptor* result) {
+    BuildFieldOrExtension(proto, parent, result, true);
+  }
+  void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto,
+                           const Descriptor* parent,
+                           Descriptor::ExtensionRange* result);
+  void BuildEnum(const EnumDescriptorProto& proto,
+                 const Descriptor* parent,
+                 EnumDescriptor* result);
+  void BuildEnumValue(const EnumValueDescriptorProto& proto,
+                      const EnumDescriptor* parent,
+                      EnumValueDescriptor* result);
+  void BuildService(const ServiceDescriptorProto& proto,
+                    const void* dummy,
+                    ServiceDescriptor* result);
+  void BuildMethod(const MethodDescriptorProto& proto,
+                   const ServiceDescriptor* parent,
+                   MethodDescriptor* result);
+
+  void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto);
+  void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto);
+  void CrossLinkField(FieldDescriptor* field,
+                      const FieldDescriptorProto& proto);
+  void CrossLinkService(ServiceDescriptor* service,
+                        const ServiceDescriptorProto& proto);
+  void CrossLinkMethod(MethodDescriptor* method,
+                       const MethodDescriptorProto& proto);
+  void CrossLinkMapKey(FieldDescriptor* field,
+                       const FieldDescriptorProto& proto);
+};
+
+const FileDescriptor* DescriptorPool::BuildFile(
+    const FileDescriptorProto& proto) {
+  GOOGLE_CHECK(fallback_database_ == NULL)
+    << "Cannot call BuildFile on a DescriptorPool that uses a "
+       "DescriptorDatabase.  You must instead find a way to get your file "
+       "into the underlying database.";
+  GOOGLE_CHECK(mutex_ == NULL);   // Implied by the above GOOGLE_CHECK.
+  return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto);
+}
+
+const FileDescriptor* DescriptorPool::BuildFileCollectingErrors(
+    const FileDescriptorProto& proto,
+    ErrorCollector* error_collector) {
+  GOOGLE_CHECK(fallback_database_ == NULL)
+    << "Cannot call BuildFile on a DescriptorPool that uses a "
+       "DescriptorDatabase.  You must instead find a way to get your file "
+       "into the underlying database.";
+  GOOGLE_CHECK(mutex_ == NULL);   // Implied by the above GOOGLE_CHECK.
+  return DescriptorBuilder(this, tables_.get(),
+                           error_collector).BuildFile(proto);
+}
+
+const FileDescriptor* DescriptorPool::BuildFileFromDatabase(
+    const FileDescriptorProto& proto) const {
+  mutex_->AssertHeld();
+  return DescriptorBuilder(this, tables_.get(),
+                           default_error_collector_).BuildFile(proto);
+}
+
+const FileDescriptor* DescriptorPool::InternalBuildGeneratedFile(
+    const void* data, int size) {
+  // So, this function is called in the process of initializing the
+  // descriptors for generated proto classes.  Each generated .pb.cc file
+  // has an internal procedure called BuildDescriptors() which is called the
+  // first time one of its descriptors is accessed, and that function calls
+  // this one in order to parse the raw bytes of the FileDescriptorProto
+  // representing the file.
+  //
+  // Note, though, that FileDescriptorProto is itself a generated protocol
+  // message.  So, when we attempt to construct one below, it will attempt
+  // to initialize its own descriptors via its own BuildDescriptors() method.
+  // This will in turn cause InternalBuildGeneratedFile() to build
+  // descriptor.proto's descriptors.
+  //
+  // We are saved from an infinite loop by the fact that BuildDescriptors()
+  // only does anything the first time it is called.  That is, the first few
+  // lines of any BuildDescriptors() procedure look like this:
+  //   void BuildDescriptors() {
+  //     static bool already_here = false;
+  //     if (already_here) return;
+  //     already_here = true;
+  //     ...
+  // So, when descriptor.pb.cc's BuildDescriptors() is called recursively, it
+  // will end up just returning without doing anything.  The result is that
+  // all of the descriptors for FileDescriptorProto and friends will just be
+  // NULL.
+  //
+  // Luckily, it turns out that our limited use of FileDescriptorProto within
+  // InternalBuildGeneratedFile() does not require that its descriptors be
+  // initialized.  So, this ends up working.  As soon as
+  // InternalBuildGeneratedFile() returns, the descriptors will be initialized
+  // by the original call to BuildDescriptors(), and everything will be happy
+  // again.
+  //
+  // If this turns out to be too fragile a hack, there are other ways we
+  // can accomplish bootstrapping here (like building the descriptor for
+  // descriptor.proto manually), but if this works then it's a lot easier.
+  //
+  // Note that because this is only triggered at static initialization time,
+  // there are no thread-safety concerns here.
+  FileDescriptorProto proto;
+  GOOGLE_CHECK(proto.ParseFromArray(data, size));
+  const FileDescriptor* result = BuildFile(proto);
+  GOOGLE_CHECK(result != NULL);
+
+  return result;
+}
+
+DescriptorBuilder::DescriptorBuilder(
+    const DescriptorPool* pool,
+    DescriptorPool::Tables* tables,
+    DescriptorPool::ErrorCollector* error_collector)
+  : pool_(pool),
+    tables_(tables),
+    error_collector_(error_collector),
+    had_errors_(false),
+    possible_undeclared_dependency_(NULL) {}
+
+DescriptorBuilder::~DescriptorBuilder() {}
+
+void DescriptorBuilder::AddError(
+    const string& element_name,
+    const Message& descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location,
+    const string& error) {
+  if (error_collector_ == NULL) {
+    if (!had_errors_) {
+      GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_
+                 << "\":";
+    }
+    GOOGLE_LOG(ERROR) << "  " << element_name << ": " << error;
+  } else {
+    error_collector_->AddError(filename_, element_name,
+                               &descriptor, location, error);
+  }
+  had_errors_ = true;
+}
+
+void DescriptorBuilder::AddNotDefinedError(
+    const string& element_name,
+    const Message& descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location,
+    const string& undefined_symbol) {
+  if (possible_undeclared_dependency_ == NULL) {
+    AddError(element_name, descriptor, location,
+             "\"" + undefined_symbol + "\" is not defined.");
+  } else {
+    AddError(element_name, descriptor, location,
+             "\"" + undefined_symbol + "\" seems to be defined in \""
+             + possible_undeclared_dependency_->name() + "\", which is not "
+             "imported by \"" + filename_ + "\".  To use it here, please "
+             "add the necessary import.");
+  }
+}
+
+bool DescriptorBuilder::IsInPackage(const FileDescriptor* file,
+                                    const string& package_name) {
+  return HasPrefixString(file->package(), package_name) &&
+           (file->package().size() == package_name.size() ||
+            file->package()[package_name.size()] == '.');
+}
+
+Symbol DescriptorBuilder::FindSymbol(const string& name) {
+  Symbol result;
+
+  // We need to search our pool and all its underlays.
+  const DescriptorPool* pool = pool_;
+  while (true) {
+    // If we are looking at an underlay, we must lock its mutex_, since we are
+    // accessing the underlay's tables_ dircetly.
+    MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_);
+
+    // Note that we don't have to check fallback_database_ here because the
+    // symbol has to be in one of its file's direct dependencies, and we have
+    // already loaded those by the time we get here.
+    result = pool->tables_->FindSymbol(name);
+    if (!result.IsNull()) break;
+    if (pool->underlay_ == NULL) return kNullSymbol;
+    pool = pool->underlay_;
+  }
+
+  if (!pool_->enforce_dependencies_) {
+    // Hack for CompilerUpgrader.
+    return result;
+  }
+
+  // Only find symbols which were defined in this file or one of its
+  // dependencies.
+  const FileDescriptor* file = result.GetFile();
+  if (file == file_) return result;
+  for (int i = 0; i < file_->dependency_count(); i++) {
+    if (file == file_->dependency(i)) return result;
+  }
+
+  if (result.type == Symbol::PACKAGE) {
+    // Arg, this is overcomplicated.  The symbol is a package name.  It could
+    // be that the package was defined in multiple files.  result.GetFile()
+    // returns the first file we saw that used this package.  We've determined
+    // that that file is not a direct dependency of the file we are currently
+    // building, but it could be that some other file which *is* a direct
+    // dependency also defines the same package.  We can't really rule out this
+    // symbol unless none of the dependencies define it.
+    if (IsInPackage(file_, name)) return result;
+    for (int i = 0; i < file_->dependency_count(); i++) {
+      if (IsInPackage(file_->dependency(i), name)) return result;
+    }
+  }
+
+  possible_undeclared_dependency_ = file;
+  return kNullSymbol;
+}
+
+Symbol DescriptorBuilder::LookupSymbol(
+    const string& name, const string& relative_to) {
+  possible_undeclared_dependency_ = NULL;
+
+  if (name.size() > 0 && name[0] == '.') {
+    // Fully-qualified name.
+    return FindSymbol(name.substr(1));
+  }
+
+  // If name is something like "Foo.Bar.baz", and symbols named "Foo" are
+  // defined in multiple parent scopes, we only want to find "Bar.baz" in the
+  // innermost one.  E.g., the following should produce an error:
+  //   message Bar { message Baz {} }
+  //   message Foo {
+  //     message Bar {
+  //     }
+  //     optional Bar.Baz baz = 1;
+  //   }
+  // So, we look for just "Foo" first, then look for "Bar.baz" within it if
+  // found.
+  int name_dot_pos = name.find_first_of('.');
+  string first_part_of_name;
+  if (name_dot_pos == string::npos) {
+    first_part_of_name = name;
+  } else {
+    first_part_of_name = name.substr(0, name_dot_pos);
+  }
+
+  string scope_to_try(relative_to);
+
+  while (true) {
+    // Chop off the last component of the scope.
+    string::size_type dot_pos = scope_to_try.find_last_of('.');
+    if (dot_pos == string::npos) {
+      return FindSymbol(name);
+    } else {
+      scope_to_try.erase(dot_pos);
+    }
+
+    // Append ".first_part_of_name" and try to find.
+    string::size_type old_size = scope_to_try.size();
+    scope_to_try.append(1, '.');
+    scope_to_try.append(first_part_of_name);
+    Symbol result = FindSymbol(scope_to_try);
+    if (!result.IsNull()) {
+      if (first_part_of_name.size() < name.size()) {
+        // name is a compound symbol, of which we only found the first part.
+        // Now try to look up the rest of it.
+        scope_to_try.append(name, first_part_of_name.size(),
+                            name.size() - first_part_of_name.size());
+        result = FindSymbol(scope_to_try);
+      }
+      return result;
+    }
+
+    // Not found.  Remove the name so we can try again.
+    scope_to_try.erase(old_size);
+  }
+}
+
+void DescriptorBuilder::AddSymbol(
+    const string& full_name, const void* parent, const string& name,
+    const Message& proto, Symbol symbol) {
+  // If the caller passed NULL for the parent, the symbol is at file scope.
+  // Use its file as the parent instead.
+  if (parent == NULL) parent = file_;
+
+  if (!tables_->AddSymbol(full_name, parent, name, symbol)) {
+    const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile();
+    if (other_file == file_) {
+      string::size_type dot_pos = full_name.find_last_of('.');
+      if (dot_pos == string::npos) {
+        AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+                 "\"" + full_name + "\" is already defined.");
+      } else {
+        AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+                 "\"" + full_name.substr(dot_pos + 1) +
+                 "\" is already defined in \"" +
+                 full_name.substr(0, dot_pos) + "\".");
+      }
+    } else {
+      // Symbol seems to have been defined in a different file.
+      AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+               "\"" + full_name + "\" is already defined in file \"" +
+               other_file->name() + "\".");
+    }
+  }
+}
+
+void DescriptorBuilder::AddPackage(
+    const string& name, const Message& proto, const FileDescriptor* file) {
+  if (tables_->AddSymbol(name, NULL, name, Symbol(file))) {
+    // Success.  Also add parent package, if any.
+    string::size_type dot_pos = name.find_last_of('.');
+    if (dot_pos == string::npos) {
+      // No parents.
+      ValidateSymbolName(name, name, proto);
+    } else {
+      // Has parent.
+      string* parent_name = tables_->AllocateString(name.substr(0, dot_pos));
+      AddPackage(*parent_name, proto, file);
+      ValidateSymbolName(name.substr(dot_pos + 1), name, proto);
+    }
+  } else {
+    Symbol existing_symbol = tables_->FindSymbol(name);
+    // It's OK to redefine a package.
+    if (existing_symbol.type != Symbol::PACKAGE) {
+      // Symbol seems to have been defined in a different file.
+      AddError(name, proto, DescriptorPool::ErrorCollector::NAME,
+               "\"" + name + "\" is already defined (as something other than "
+               "a package) in file \"" + existing_symbol.GetFile()->name() +
+               "\".");
+    }
+  }
+}
+
+void DescriptorBuilder::ValidateSymbolName(
+    const string& name, const string& full_name, const Message& proto) {
+  if (name.empty()) {
+    AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+             "Missing name.");
+  } else {
+    for (int i = 0; i < name.size(); i++) {
+      // I don't trust isalnum() due to locales.  :(
+      if ((name[i] < 'a' || 'z' < name[i]) &&
+          (name[i] < 'A' || 'Z' < name[i]) &&
+          (name[i] < '0' || '9' < name[i]) &&
+          (name[i] != '_')) {
+        AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+                 "\"" + name + "\" is not a valid identifier.");
+      }
+    }
+  }
+}
+
+// -------------------------------------------------------------------
+
+// A common pattern:  We want to convert a repeated field in the descriptor
+// to an array of values, calling some method to build each value.
+#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT)             \
+  OUTPUT->NAME##_count_ = INPUT.NAME##_size();                       \
+  AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_);             \
+  for (int i = 0; i < INPUT.NAME##_size(); i++) {                    \
+    METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i);             \
+  }
+
+const FileDescriptor* DescriptorBuilder::BuildFile(
+    const FileDescriptorProto& proto) {
+  filename_ = proto.name();
+
+  // Check to see if this file is already on the pending files list.
+  // TODO(kenton):  Allow recursive imports?  It may not work with some
+  //   (most?) programming languages.  E.g., in C++, a forward declaration
+  //   of a type is not sufficient to allow it to be used even in a
+  //   generated header file due to inlining.  This could perhaps be
+  //   worked around using tricks involving inserting #include statements
+  //   mid-file, but that's pretty ugly, and I'm pretty sure there are
+  //   some languages out there that do not allow recursive dependencies
+  //   at all.
+  for (int i = 0; i < tables_->pending_files_.size(); i++) {
+    if (tables_->pending_files_[i] == proto.name()) {
+      string error_message("File recursively imports itself: ");
+      for (; i < tables_->pending_files_.size(); i++) {
+        error_message.append(tables_->pending_files_[i]);
+        error_message.append(" -> ");
+      }
+      error_message.append(proto.name());
+
+      AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+               error_message);
+      return NULL;
+    }
+  }
+
+  // If we have a fallback_database_, attempt to load all dependencies now,
+  // before checkpointing tables_.  This avoids confusion with recursive
+  // checkpoints.
+  if (pool_->fallback_database_ != NULL) {
+    tables_->pending_files_.push_back(proto.name());
+    for (int i = 0; i < proto.dependency_size(); i++) {
+      if (tables_->FindFile(proto.dependency(i)) == NULL &&
+          (pool_->underlay_ == NULL ||
+           pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) {
+        // We don't care what this returns since we'll find out below anyway.
+        pool_->TryFindFileInFallbackDatabase(proto.dependency(i));
+      }
+    }
+    tables_->pending_files_.pop_back();
+  }
+
+  // Checkpoint the tables so that we can roll back if something goes wrong.
+  tables_->Checkpoint();
+
+  FileDescriptor* result = tables_->Allocate<FileDescriptor>();
+  file_ = result;
+
+  if (!proto.has_name()) {
+    AddError("", proto, DescriptorPool::ErrorCollector::OTHER,
+             "Missing field: FileDescriptorProto.name.");
+  }
+
+  result->name_ = tables_->AllocateString(proto.name());
+  result->package_ = tables_->AllocateString(proto.package());
+  result->pool_ = pool_;
+
+  // Add to tables.
+  if (!tables_->AddFile(result)) {
+    AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+             "A file with this name is already in the pool.");
+    // Bail out early so that if this is actually the exact same file, we
+    // don't end up reporting that every single symbol is already defined.
+    tables_->Rollback();
+    return NULL;
+  }
+  if (!result->package().empty()) {
+    AddPackage(result->package(), proto, result);
+  }
+
+  // Make sure all dependencies are loaded.
+  set<string> seen_dependencies;
+  result->dependency_count_ = proto.dependency_size();
+  result->dependencies_ =
+    tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size());
+  for (int i = 0; i < proto.dependency_size(); i++) {
+    if (!seen_dependencies.insert(proto.dependency(i)).second) {
+      AddError(proto.name(), proto,
+               DescriptorPool::ErrorCollector::OTHER,
+               "Import \"" + proto.dependency(i) + "\" was listed twice.");
+    }
+
+    const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i));
+    if (dependency == NULL && pool_->underlay_ != NULL) {
+      dependency = pool_->underlay_->FindFileByName(proto.dependency(i));
+    }
+
+    if (dependency == NULL) {
+      string message;
+      if (pool_->fallback_database_ == NULL) {
+        message = "Import \"" + proto.dependency(i) +
+                  "\" has not been loaded.";
+      } else {
+        message = "Import \"" + proto.dependency(i) +
+                  "\" was not found or had errors.";
+      }
+      AddError(proto.name(), proto,
+               DescriptorPool::ErrorCollector::OTHER,
+               message);
+    }
+
+    result->dependencies_[i] = dependency;
+  }
+
+  // Convert children.
+  BUILD_ARRAY(proto, result, message_type, BuildMessage  , NULL);
+  BUILD_ARRAY(proto, result, enum_type   , BuildEnum     , NULL);
+  BUILD_ARRAY(proto, result, service     , BuildService  , NULL);
+  BUILD_ARRAY(proto, result, extension   , BuildExtension, NULL);
+
+  // Copy options.
+  if (!proto.has_options()) {
+    result->options_ = &FileOptions::default_instance();
+  } else {
+    FileOptions* options = tables_->AllocateMessage<FileOptions>();
+    options->CopyFrom(proto.options());
+    result->options_ = options;
+  }
+
+  // Cross-link.
+  CrossLinkFile(result, proto);
+
+  if (had_errors_) {
+    tables_->Rollback();
+    return NULL;
+  } else {
+    tables_->Checkpoint();
+    return result;
+  }
+}
+
+void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
+                                     const Descriptor* parent,
+                                     Descriptor* result) {
+  const string& scope = (parent == NULL) ?
+    file_->package() : parent->full_name();
+  string* full_name = tables_->AllocateString(scope);
+  if (!full_name->empty()) full_name->append(1, '.');
+  full_name->append(proto.name());
+
+  ValidateSymbolName(proto.name(), *full_name, proto);
+
+  result->name_            = tables_->AllocateString(proto.name());
+  result->full_name_       = full_name;
+  result->file_            = file_;
+  result->containing_type_ = parent;
+
+  BUILD_ARRAY(proto, result, field          , BuildField         , result);
+  BUILD_ARRAY(proto, result, nested_type    , BuildMessage       , result);
+  BUILD_ARRAY(proto, result, enum_type      , BuildEnum          , result);
+  BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result);
+  BUILD_ARRAY(proto, result, extension      , BuildExtension     , result);
+
+  // Copy options.
+  if (!proto.has_options()) {
+    result->options_ = &MessageOptions::default_instance();
+  } else {
+    MessageOptions* options = tables_->AllocateMessage<MessageOptions>();
+    options->CopyFrom(proto.options());
+    result->options_ = options;
+  }
+
+  AddSymbol(result->full_name(), parent, result->name(),
+            proto, Symbol(result));
+
+  // Check that no fields have numbers in extension ranges.
+  for (int i = 0; i < result->field_count(); i++) {
+    const FieldDescriptor* field = result->field(i);
+    for (int j = 0; j < result->extension_range_count(); j++) {
+      const Descriptor::ExtensionRange* range = result->extension_range(j);
+      if (range->start <= field->number() && field->number() < range->end) {
+        AddError(field->full_name(), proto.extension_range(j),
+                 DescriptorPool::ErrorCollector::NUMBER,
+                 strings::Substitute(
+                   "Extension range $0 to $1 includes field \"$2\" ($3).",
+                   range->start, range->end - 1,
+                   field->name(), field->number()));
+      }
+    }
+  }
+
+  // Check that extension ranges don't overlap.
+  for (int i = 0; i < result->extension_range_count(); i++) {
+    const Descriptor::ExtensionRange* range1 = result->extension_range(i);
+    for (int j = i + 1; j < result->extension_range_count(); j++) {
+      const Descriptor::ExtensionRange* range2 = result->extension_range(j);
+      if (range1->end > range2->start && range2->end > range1->start) {
+        AddError(result->full_name(), proto.extension_range(j),
+                 DescriptorPool::ErrorCollector::NUMBER,
+                 strings::Substitute("Extension range $0 to $1 overlaps with "
+                                     "already-defined range $2 to $3.",
+                                     range2->start, range2->end - 1,
+                                     range1->start, range1->end - 1));
+      }
+    }
+  }
+}
+
+void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
+                                              const Descriptor* parent,
+                                              FieldDescriptor* result,
+                                              bool is_extension) {
+  const string& scope = (parent == NULL) ?
+    file_->package() : parent->full_name();
+  string* full_name = tables_->AllocateString(scope);
+  if (!full_name->empty()) full_name->append(1, '.');
+  full_name->append(proto.name());
+
+  ValidateSymbolName(proto.name(), *full_name, proto);
+
+  result->name_         = tables_->AllocateString(proto.name());
+  result->full_name_    = full_name;
+  result->file_         = file_;
+  result->number_       = proto.number();
+  result->type_         = static_cast<FieldDescriptor::Type>(proto.type());
+  result->label_        = static_cast<FieldDescriptor::Label>(proto.label());
+  result->is_extension_ = is_extension;
+
+  // Some of these may be filled in when cross-linking.
+  result->containing_type_ = NULL;
+  result->extension_scope_ = NULL;
+  result->experimental_map_key_ = NULL;
+  result->message_type_ = NULL;
+  result->enum_type_ = NULL;
+
+  result->has_default_value_ = proto.has_default_value();
+  if (proto.has_type()) {
+    if (proto.has_default_value()) {
+      char* end_pos = NULL;
+      switch (result->cpp_type()) {
+        case FieldDescriptor::CPPTYPE_INT32:
+          result->default_value_int32_ =
+            strtol(proto.default_value().c_str(), &end_pos, 0);
+          break;
+        case FieldDescriptor::CPPTYPE_INT64:
+          result->default_value_int64_ =
+            strto64(proto.default_value().c_str(), &end_pos, 0);
+          break;
+        case FieldDescriptor::CPPTYPE_UINT32:
+          result->default_value_uint32_ =
+            strtoul(proto.default_value().c_str(), &end_pos, 0);
+          break;
+        case FieldDescriptor::CPPTYPE_UINT64:
+          result->default_value_uint64_ =
+            strtou64(proto.default_value().c_str(), &end_pos, 0);
+          break;
+        case FieldDescriptor::CPPTYPE_FLOAT:
+          result->default_value_float_ =
+            NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
+          break;
+        case FieldDescriptor::CPPTYPE_DOUBLE:
+          result->default_value_double_ =
+            NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
+          break;
+        case FieldDescriptor::CPPTYPE_BOOL:
+          if (proto.default_value() == "true") {
+            result->default_value_bool_ = true;
+          } else if (proto.default_value() == "false") {
+            result->default_value_bool_ = false;
+          } else {
+            AddError(result->full_name(), proto,
+                     DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+                     "Boolean default must be true or false.");
+          }
+          break;
+        case FieldDescriptor::CPPTYPE_ENUM:
+          // This will be filled in when cross-linking.
+          result->default_value_enum_ = NULL;
+          break;
+        case FieldDescriptor::CPPTYPE_STRING:
+          if (result->type() == FieldDescriptor::TYPE_BYTES) {
+            result->default_value_string_ = tables_->AllocateString(
+              UnescapeCEscapeString(proto.default_value()));
+          } else {
+            result->default_value_string_ =
+              tables_->AllocateString(proto.default_value());
+          }
+          break;
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          AddError(result->full_name(), proto,
+                   DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+                   "Messages can't have default values.");
+          result->has_default_value_ = false;
+          break;
+      }
+
+      if (end_pos != NULL) {
+        // end_pos is only set non-NULL by the parsers for numeric types, above.
+        // This checks that the default was non-empty and had no extra junk
+        // after the end of the number.
+        if (proto.default_value().empty() || *end_pos != '\0') {
+          AddError(result->full_name(), proto,
+                   DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+                   "Couldn't parse default value.");
+        }
+      }
+    } else {
+      // No explicit default value
+      switch (result->cpp_type()) {
+        case FieldDescriptor::CPPTYPE_INT32:
+          result->default_value_int32_ = 0;
+          break;
+        case FieldDescriptor::CPPTYPE_INT64:
+          result->default_value_int64_ = 0;
+          break;
+        case FieldDescriptor::CPPTYPE_UINT32:
+          result->default_value_uint32_ = 0;
+          break;
+        case FieldDescriptor::CPPTYPE_UINT64:
+          result->default_value_uint64_ = 0;
+          break;
+        case FieldDescriptor::CPPTYPE_FLOAT:
+          result->default_value_float_ = 0.0f;
+          break;
+        case FieldDescriptor::CPPTYPE_DOUBLE:
+          result->default_value_double_ = 0.0;
+          break;
+        case FieldDescriptor::CPPTYPE_BOOL:
+          result->default_value_bool_ = false;
+          break;
+        case FieldDescriptor::CPPTYPE_ENUM:
+          // This will be filled in when cross-linking.
+          result->default_value_enum_ = NULL;
+          break;
+        case FieldDescriptor::CPPTYPE_STRING:
+          result->default_value_string_ = &kEmptyString;
+          break;
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          break;
+      }
+    }
+  }
+
+  if (result->number() <= 0) {
+    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+             "Field numbers must be positive integers.");
+  } else if (result->number() > FieldDescriptor::kMaxNumber) {
+    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+             strings::Substitute("Field numbers cannot be greater than $0.",
+                                 FieldDescriptor::kMaxNumber));
+  } else if (result->number() >= FieldDescriptor::kFirstReservedNumber &&
+             result->number() <= FieldDescriptor::kLastReservedNumber) {
+    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+             strings::Substitute(
+               "Field numbers $0 through $1 are reserved for the protocol "
+               "buffer library implementation.",
+               FieldDescriptor::kFirstReservedNumber,
+               FieldDescriptor::kLastReservedNumber));
+  }
+
+  if (is_extension) {
+    if (!proto.has_extendee()) {
+      AddError(result->full_name(), proto,
+               DescriptorPool::ErrorCollector::EXTENDEE,
+               "FieldDescriptorProto.extendee not set for extension field.");
+    }
+
+    result->extension_scope_ = parent;
+  } else {
+    if (proto.has_extendee()) {
+      AddError(result->full_name(), proto,
+               DescriptorPool::ErrorCollector::EXTENDEE,
+               "FieldDescriptorProto.extendee set for non-extension field.");
+    }
+
+    result->containing_type_ = parent;
+  }
+
+  // Copy options.
+  if (!proto.has_options()) {
+    result->options_ = &FieldOptions::default_instance();
+  } else {
+    FieldOptions* options = tables_->AllocateMessage<FieldOptions>();
+    options->CopyFrom(proto.options());
+    result->options_ = options;
+  }
+
+  AddSymbol(result->full_name(), parent, result->name(),
+            proto, Symbol(result));
+}
+
+void DescriptorBuilder::BuildExtensionRange(
+    const DescriptorProto::ExtensionRange& proto,
+    const Descriptor* parent,
+    Descriptor::ExtensionRange* result) {
+  result->start = proto.start();
+  result->end = proto.end();
+  if (result->start <= 0) {
+    AddError(parent->full_name(), proto,
+             DescriptorPool::ErrorCollector::NUMBER,
+             "Extension numbers must be positive integers.");
+  }
+
+  if (result->end > FieldDescriptor::kMaxNumber + 1) {
+    AddError(parent->full_name(), proto,
+             DescriptorPool::ErrorCollector::NUMBER,
+             strings::Substitute("Extension numbers cannot be greater than $0.",
+                                 FieldDescriptor::kMaxNumber));
+  }
+
+  if (result->start >= result->end) {
+    AddError(parent->full_name(), proto,
+             DescriptorPool::ErrorCollector::NUMBER,
+             "Extension range end number must be greater than start number.");
+  }
+}
+
+void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto,
+                                  const Descriptor* parent,
+                                  EnumDescriptor* result) {
+  const string& scope = (parent == NULL) ?
+    file_->package() : parent->full_name();
+  string* full_name = tables_->AllocateString(scope);
+  if (!full_name->empty()) full_name->append(1, '.');
+  full_name->append(proto.name());
+
+  ValidateSymbolName(proto.name(), *full_name, proto);
+
+  result->name_            = tables_->AllocateString(proto.name());
+  result->full_name_       = full_name;
+  result->file_            = file_;
+  result->containing_type_ = parent;
+
+  if (proto.value_size() == 0) {
+    // We cannot allow enums with no values because this would mean there
+    // would be no valid default value for fields of this type.
+    AddError(result->full_name(), proto,
+             DescriptorPool::ErrorCollector::NAME,
+             "Enums must contain at least one value.");
+  }
+
+  BUILD_ARRAY(proto, result, value, BuildEnumValue, result);
+
+  // Copy options.
+  if (!proto.has_options()) {
+    result->options_ = &EnumOptions::default_instance();
+  } else {
+    EnumOptions* options = tables_->AllocateMessage<EnumOptions>();
+    options->CopyFrom(proto.options());
+    result->options_ = options;
+  }
+
+  AddSymbol(result->full_name(), parent, result->name(),
+            proto, Symbol(result));
+}
+
+void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto,
+                                       const EnumDescriptor* parent,
+                                       EnumValueDescriptor* result) {
+  result->name_   = tables_->AllocateString(proto.name());
+  result->number_ = proto.number();
+  result->type_   = parent;
+
+  // Note:  full_name for enum values is a sibling to the parent's name, not a
+  //   child of it.
+  string* full_name = tables_->AllocateString(*parent->full_name_);
+  full_name->resize(full_name->size() - parent->name_->size());
+  full_name->append(*result->name_);
+  result->full_name_ = full_name;
+
+  ValidateSymbolName(proto.name(), *full_name, proto);
+
+  // Copy options.
+  if (!proto.has_options()) {
+    result->options_ = &EnumValueOptions::default_instance();
+  } else {
+    EnumValueOptions* options = tables_->AllocateMessage<EnumValueOptions>();
+    options->CopyFrom(proto.options());
+    result->options_ = options;
+  }
+
+  // Again, enum values are weird because we makes them appear as siblings
+  // of the enum type instead of children of it.  So, we use
+  // parent->containing_type() as the value's parent.
+  AddSymbol(result->full_name(), parent->containing_type(), result->name(),
+            proto, Symbol(result));
+
+  // However, we also want to be able to search for values within a single
+  // enum type, so we add it as a child of the enum type itself, too.
+  // Note:  This could fail, but if it does, the error has already been
+  //   reported by the above AddSymbol() call, so we ignore the return code.
+  tables_->AddAliasUnderParent(parent, result->name(), Symbol(result));
+
+  // An enum is allowed to define two numbers that refer to the same value.
+  // FindValueByNumber() should return the first such value, so we simply
+  // ignore AddEnumValueByNumber()'s return code.
+  tables_->AddEnumValueByNumber(result);
+}
+
+void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto,
+                                     const void* dummy,
+                                     ServiceDescriptor* result) {
+  string* full_name = tables_->AllocateString(file_->package());
+  if (!full_name->empty()) full_name->append(1, '.');
+  full_name->append(proto.name());
+
+  ValidateSymbolName(proto.name(), *full_name, proto);
+
+  result->name_      = tables_->AllocateString(proto.name());
+  result->full_name_ = full_name;
+  result->file_      = file_;
+
+  BUILD_ARRAY(proto, result, method, BuildMethod, result);
+
+  // Copy options.
+  if (!proto.has_options()) {
+    result->options_ = &ServiceOptions::default_instance();
+  } else {
+    ServiceOptions* options = tables_->AllocateMessage<ServiceOptions>();
+    options->CopyFrom(proto.options());
+    result->options_ = options;
+  }
+
+  AddSymbol(result->full_name(), NULL, result->name(),
+            proto, Symbol(result));
+}
+
+void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto,
+                                    const ServiceDescriptor* parent,
+                                    MethodDescriptor* result) {
+  result->name_    = tables_->AllocateString(proto.name());
+  result->service_ = parent;
+
+  string* full_name = tables_->AllocateString(parent->full_name());
+  full_name->append(1, '.');
+  full_name->append(*result->name_);
+  result->full_name_ = full_name;
+
+  ValidateSymbolName(proto.name(), *full_name, proto);
+
+  // These will be filled in when cross-linking.
+  result->input_type_ = NULL;
+  result->output_type_ = NULL;
+
+  // Copy options.
+  if (!proto.has_options()) {
+    result->options_ = &MethodOptions::default_instance();
+  } else {
+    MethodOptions* options = tables_->AllocateMessage<MethodOptions>();
+    options->CopyFrom(proto.options());
+    result->options_ = options;
+  }
+
+  AddSymbol(result->full_name(), parent, result->name(),
+            proto, Symbol(result));
+}
+
+#undef BUILD_ARRAY
+
+// -------------------------------------------------------------------
+
+void DescriptorBuilder::CrossLinkFile(
+    FileDescriptor* file, const FileDescriptorProto& proto) {
+  for (int i = 0; i < file->message_type_count(); i++) {
+    CrossLinkMessage(&file->message_types_[i], proto.message_type(i));
+  }
+
+  for (int i = 0; i < file->extension_count(); i++) {
+    CrossLinkField(&file->extensions_[i], proto.extension(i));
+  }
+
+  for (int i = 0; i < file->service_count(); i++) {
+    CrossLinkService(&file->services_[i], proto.service(i));
+  }
+}
+
+void DescriptorBuilder::CrossLinkMessage(
+    Descriptor* message, const DescriptorProto& proto) {
+  for (int i = 0; i < message->nested_type_count(); i++) {
+    CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i));
+  }
+
+  for (int i = 0; i < message->field_count(); i++) {
+    CrossLinkField(&message->fields_[i], proto.field(i));
+  }
+
+  for (int i = 0; i < message->extension_count(); i++) {
+    CrossLinkField(&message->extensions_[i], proto.extension(i));
+  }
+}
+
+void DescriptorBuilder::CrossLinkField(
+    FieldDescriptor* field, const FieldDescriptorProto& proto) {
+  if (proto.has_extendee()) {
+    Symbol extendee = LookupSymbol(proto.extendee(), field->full_name());
+    if (extendee.IsNull()) {
+      AddNotDefinedError(field->full_name(), proto,
+                         DescriptorPool::ErrorCollector::EXTENDEE,
+                         proto.extendee());
+      return;
+    } else if (extendee.type != Symbol::MESSAGE) {
+      AddError(field->full_name(), proto,
+               DescriptorPool::ErrorCollector::EXTENDEE,
+               "\"" + proto.extendee() + "\" is not a message type.");
+      return;
+    }
+    field->containing_type_ = extendee.descriptor;
+
+    if (!field->containing_type()->IsExtensionNumber(field->number())) {
+      AddError(field->full_name(), proto,
+               DescriptorPool::ErrorCollector::NUMBER,
+               strings::Substitute("\"$0\" does not declare $1 as an "
+                                   "extension number.",
+                                   field->containing_type()->full_name(),
+                                   field->number()));
+    }
+  }
+
+  if (proto.has_type_name()) {
+    Symbol type = LookupSymbol(proto.type_name(), field->full_name());
+    if (type.IsNull()) {
+      AddNotDefinedError(field->full_name(), proto,
+                         DescriptorPool::ErrorCollector::TYPE,
+                         proto.type_name());
+      return;
+    }
+
+    if (!proto.has_type()) {
+      // Choose field type based on symbol.
+      if (type.type == Symbol::MESSAGE) {
+        field->type_ = FieldDescriptor::TYPE_MESSAGE;
+      } else if (type.type == Symbol::ENUM) {
+        field->type_ = FieldDescriptor::TYPE_ENUM;
+      } else {
+        AddError(field->full_name(), proto,
+                 DescriptorPool::ErrorCollector::TYPE,
+                 "\"" + proto.type_name() + "\" is not a type.");
+        return;
+      }
+    }
+
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (type.type != Symbol::MESSAGE) {
+        AddError(field->full_name(), proto,
+                 DescriptorPool::ErrorCollector::TYPE,
+                 "\"" + proto.type_name() + "\" is not a message type.");
+        return;
+      }
+      field->message_type_ = type.descriptor;
+
+      if (field->has_default_value()) {
+        AddError(field->full_name(), proto,
+                 DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+                 "Messages can't have default values.");
+      }
+    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+      if (type.type != Symbol::ENUM) {
+        AddError(field->full_name(), proto,
+                 DescriptorPool::ErrorCollector::TYPE,
+                 "\"" + proto.type_name() + "\" is not an enum type.");
+        return;
+      }
+      field->enum_type_ = type.enum_descriptor;
+
+      if (field->has_default_value()) {
+        // We can't just use field->enum_type()->FindValueByName() here
+        // because that locks the pool's mutex, which we have already locked
+        // at this point.
+        Symbol default_value =
+          LookupSymbol(proto.default_value(), field->enum_type()->full_name());
+
+        if (default_value.type == Symbol::ENUM_VALUE &&
+            default_value.enum_value_descriptor->type() == field->enum_type()) {
+          field->default_value_enum_ = default_value.enum_value_descriptor;
+        } else {
+          AddError(field->full_name(), proto,
+                   DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+                   "Enum type \"" + field->enum_type()->full_name() +
+                   "\" has no value named \"" + proto.default_value() + "\".");
+        }
+      } else if (field->enum_type()->value_count() > 0) {
+        // All enums must have at least one value, or we would have reported
+        // an error elsewhere.  We use the first defined value as the default
+        // if a default is not explicitly defined.
+        field->default_value_enum_ = field->enum_type()->value(0);
+      }
+    } else {
+      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+               "Field with primitive type has type_name.");
+    }
+  } else {
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
+        field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+               "Field with message or enum type missing type_name.");
+    }
+  }
+
+  if (proto.has_options() && proto.options().has_experimental_map_key()) {
+    CrossLinkMapKey(field, proto);
+  }
+
+  // Add the field to the fields-by-number table.
+  // Note:  We have to do this *after* cross-linking because extensions do not
+  //   know their containing type until now.
+  if (!tables_->AddFieldByNumber(field)) {
+    const FieldDescriptor* conflicting_field =
+      tables_->FindFieldByNumber(field->containing_type(), field->number());
+    if (field->is_extension()) {
+      AddError(field->full_name(), proto,
+               DescriptorPool::ErrorCollector::NUMBER,
+               strings::Substitute("Extension number $0 has already been used "
+                                   "in \"$1\" by extension \"$2\".",
+                                   field->number(),
+                                   field->containing_type()->full_name(),
+                                   conflicting_field->full_name()));
+    } else {
+      AddError(field->full_name(), proto,
+               DescriptorPool::ErrorCollector::NUMBER,
+               strings::Substitute("Field number $0 has already been used in "
+                                   "\"$1\" by field \"$2\".",
+                                   field->number(),
+                                   field->containing_type()->full_name(),
+                                   conflicting_field->name()));
+    }
+  }
+
+  // Note:  Default instance may not yet be initialized here, so we have to
+  //   avoid reading from it.
+  if (field->containing_type_ != NULL &&
+      &field->containing_type()->options() !=
+        &MessageOptions::default_instance() &&
+      field->containing_type()->options().message_set_wire_format()) {
+    if (field->is_extension()) {
+      if (!field->is_optional() ||
+          field->type() != FieldDescriptor::TYPE_MESSAGE) {
+        AddError(field->full_name(), proto,
+                 DescriptorPool::ErrorCollector::TYPE,
+                 "Extensions of MessageSets must be optional messages.");
+      }
+    } else {
+      AddError(field->full_name(), proto,
+               DescriptorPool::ErrorCollector::NAME,
+               "MessageSets cannot have fields, only extensions.");
+    }
+  }
+}
+
+void DescriptorBuilder::CrossLinkService(
+    ServiceDescriptor* service, const ServiceDescriptorProto& proto) {
+  for (int i = 0; i < service->method_count(); i++) {
+    CrossLinkMethod(&service->methods_[i], proto.method(i));
+  }
+}
+
+void DescriptorBuilder::CrossLinkMethod(
+    MethodDescriptor* method, const MethodDescriptorProto& proto) {
+  Symbol input_type = LookupSymbol(proto.input_type(), method->full_name());
+  if (input_type.IsNull()) {
+    AddNotDefinedError(method->full_name(), proto,
+                       DescriptorPool::ErrorCollector::INPUT_TYPE,
+                       proto.input_type());
+  } else if (input_type.type != Symbol::MESSAGE) {
+    AddError(method->full_name(), proto,
+             DescriptorPool::ErrorCollector::INPUT_TYPE,
+             "\"" + proto.input_type() + "\" is not a message type.");
+  } else {
+    method->input_type_ = input_type.descriptor;
+  }
+
+  Symbol output_type = LookupSymbol(proto.output_type(), method->full_name());
+  if (output_type.IsNull()) {
+    AddNotDefinedError(method->full_name(), proto,
+                       DescriptorPool::ErrorCollector::OUTPUT_TYPE,
+                       proto.output_type());
+  } else if (output_type.type != Symbol::MESSAGE) {
+    AddError(method->full_name(), proto,
+             DescriptorPool::ErrorCollector::OUTPUT_TYPE,
+             "\"" + proto.output_type() + "\" is not a message type.");
+  } else {
+    method->output_type_ = output_type.descriptor;
+  }
+}
+
+void DescriptorBuilder::CrossLinkMapKey(
+    FieldDescriptor* field,
+    const FieldDescriptorProto& proto) {
+  if (!field->is_repeated()) {
+    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+             "map type is only allowed for repeated fields.");
+    return;
+  }
+
+  if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+             "map type is only allowed for fields with a message type.");
+    return;
+  }
+
+  const Descriptor* item_type = field->message_type();
+  if (item_type == NULL) {
+    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+             "Could not find field type.");
+    return;
+  }
+
+  // Find the field in item_type named by "experimental_map_key"
+  const string& key_name = proto.options().experimental_map_key();
+  const Symbol key_symbol = LookupSymbol(
+      key_name,
+      // We append ".key_name" to the containing type's name since
+      // LookupSymbol() searches for peers of the supplied name, not
+      // children of the supplied name.
+      item_type->full_name() + "." + key_name);
+
+  if (key_symbol.IsNull() || key_symbol.field_descriptor->is_extension()) {
+    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+             "Could not find field named \"" + key_name + "\" in type \"" +
+             item_type->full_name() + "\".");
+    return;
+  }
+  const FieldDescriptor* key_field = key_symbol.field_descriptor;
+
+  if (key_field->is_repeated()) {
+    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+             "map_key must not name a repeated field.");
+    return;
+  }
+
+  if (key_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+             "map key must name a scalar or string field.");
+    return;
+  }
+
+  field->experimental_map_key_ = key_field;
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
new file mode 100644
index 0000000..2bba4c3
--- /dev/null
+++ b/src/google/protobuf/descriptor.h
@@ -0,0 +1,1173 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains classes which describe a type of protocol message.
+// You can use a message's descriptor to learn at runtime what fields
+// it contains and what the types of those fields are.  The Message
+// interface also allows you to dynamically access and modify individual
+// fields by passing the FieldDescriptor of the field you are interested
+// in.
+//
+// Most users will not care about descriptors, because they will write
+// code specific to certain protocol types and will simply use the classes
+// generated by the protocol compiler directly.  Advanced users who want
+// to operate on arbitrary types (not known at compile time) may want to
+// read descriptors in order to learn about the contents of a message.
+// A very small number of users will want to construct their own
+// Descriptors, either because they are implementing Message manually or
+// because they are writing something like the protocol compiler.
+//
+// For an example of how you might use descriptors, see the code example
+// at the top of message.h.
+
+#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__
+#define GOOGLE_PROTOBUF_DESCRIPTOR_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+
+
+namespace google {
+namespace protobuf {
+
+// Defined in this file.
+class Descriptor;
+class FieldDescriptor;
+class EnumDescriptor;
+class EnumValueDescriptor;
+class ServiceDescriptor;
+class MethodDescriptor;
+class FileDescriptor;
+class DescriptorDatabase;
+class DescriptorPool;
+
+// Defined in descriptor.proto
+class DescriptorProto;
+class FieldDescriptorProto;
+class EnumDescriptorProto;
+class EnumValueDescriptorProto;
+class ServiceDescriptorProto;
+class MethodDescriptorProto;
+class FileDescriptorProto;
+class MessageOptions;
+class FieldOptions;
+class EnumOptions;
+class EnumValueOptions;
+class ServiceOptions;
+class MethodOptions;
+class FileOptions;
+
+// Defined in message.h
+class Message;
+
+// Defined in descriptor.cc
+class DescriptorBuilder;
+
+// Describes a type of protocol message, or a particular group within a
+// message.  To obtain the Descriptor for a given message object, call
+// Message::GetDescriptor().  Generated message classes also have a
+// static method called descriptor() which returns the type's descriptor.
+// Use DescriptorPool to construct your own descriptors.
+class LIBPROTOBUF_EXPORT Descriptor {
+ public:
+  // The name of the message type, not including its scope.
+  const string& name() const;
+
+  // The fully-qualified name of the message type, scope delimited by
+  // periods.  For example, message type "Foo" which is declared in package
+  // "bar" has full name "bar.Foo".  If a type "Baz" is nested within
+  // Foo, Baz's full_name is "bar.Foo.Baz".  To get only the part that
+  // comes after the last '.', use name().
+  const string& full_name() const;
+
+  // Index of this descriptor within the file or containing type's message
+  // type array.
+  int index() const;
+
+  // The .proto file in which this message type was defined.  Never NULL.
+  const FileDescriptor* file() const;
+
+  // If this Descriptor describes a nested type, this returns the type
+  // in which it is nested.  Otherwise, returns NULL.
+  const Descriptor* containing_type() const;
+
+  // Get options for this message type.  These are specified in the .proto
+  // file by placing lines like "option foo = 1234;" in the message definition.
+  // The exact set of known options is defined by MessageOptions in
+  // google/protobuf/descriptor.proto.
+  const MessageOptions& options() const;
+
+  // Write the contents of this Descriptor into the given DescriptorProto.
+  // The target DescriptorProto must be clear before calling this; if it
+  // isn't, the result may be garbage.
+  void CopyTo(DescriptorProto* proto) const;
+
+  // Write the contents of this decriptor in a human-readable form. Output
+  // will be suitable for re-parsing.
+  string DebugString() const;
+
+  // Field stuff -----------------------------------------------------
+
+  // The number of fields in this message type.
+  int field_count() const;
+  // Gets a field by index, where 0 <= index < field_count().
+  const FieldDescriptor* field(int index) const;
+
+  // Looks up a field by declared tag number.  Returns NULL if no such field
+  // exists.
+  const FieldDescriptor* FindFieldByNumber(int number) const;
+  // Looks up a field by name.  Returns NULL if no such field exists.
+  const FieldDescriptor* FindFieldByName(const string& name) const;
+
+  // Nested type stuff -----------------------------------------------
+
+  // The number of nested types in this message type.
+  int nested_type_count() const;
+  // Gets a nested type by index, where 0 <= index < nested_type_count().
+  const Descriptor* nested_type(int index) const;
+
+  // Looks up a nested type by name.  Returns NULL if no such nested type
+  // exists.
+  const Descriptor* FindNestedTypeByName(const string& name) const;
+
+  // Enum stuff ------------------------------------------------------
+
+  // The number of enum types in this message type.
+  int enum_type_count() const;
+  // Gets an enum type by index, where 0 <= index < enum_type_count().
+  const EnumDescriptor* enum_type(int index) const;
+
+  // Looks up an enum type by name.  Returns NULL if no such enum type exists.
+  const EnumDescriptor* FindEnumTypeByName(const string& name) const;
+
+  // Looks up an enum value by name, among all enum types in this message.
+  // Returns NULL if no such value exists.
+  const EnumValueDescriptor* FindEnumValueByName(const string& name) const;
+
+  // Extensions ------------------------------------------------------
+
+  // A range of field numbers which are designated for third-party
+  // extensions.
+  struct ExtensionRange {
+    int start;  // inclusive
+    int end;    // exclusive
+  };
+
+  // The number of extension ranges in this message type.
+  int extension_range_count() const;
+  // Gets an extension range by index, where 0 <= index <
+  // extension_range_count().
+  const ExtensionRange* extension_range(int index) const;
+
+  // Returns true if the number is in one of the extension ranges.
+  bool IsExtensionNumber(int number) const;
+
+  // The number of extensions -- extending *other* messages -- that were
+  // defined nested within this message type's scope.
+  int extension_count() const;
+  // Get an extension by index, where 0 <= index < extension_count().
+  const FieldDescriptor* extension(int index) const;
+
+  // Looks up a named extension (which extends some *other* message type)
+  // defined within this message type's scope.
+  const FieldDescriptor* FindExtensionByName(const string& name) const;
+
+ private:
+  // Internal version of DebugString; controls the level of indenting for
+  // correct depth
+  void DebugString(int depth, string *contents) const;
+
+  const string* name_;
+  const string* full_name_;
+  const FileDescriptor* file_;
+  const Descriptor* containing_type_;
+  const MessageOptions* options_;
+  int field_count_;
+  FieldDescriptor* fields_;
+  int nested_type_count_;
+  Descriptor* nested_types_;
+  int enum_type_count_;
+  EnumDescriptor* enum_types_;
+  int extension_range_count_;
+  ExtensionRange* extension_ranges_;
+  int extension_count_;
+  FieldDescriptor* extensions_;
+
+  // Must be constructed using DescriptorPool.
+  Descriptor() {}
+  friend class DescriptorBuilder;
+  friend class EnumDescriptor;
+  friend class FieldDescriptor;
+  friend class FileDescriptor;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor);
+};
+
+// Describes a single field of a message.  To get the descriptor for a given
+// field, first get the Descriptor for the message in which it is defined,
+// then call Descriptor::FindFieldByName().  To get a FieldDescriptor for
+// an extension, do one of the following:
+// - Get the Descriptor or FileDescriptor for its containing scope, then
+//   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().
+// Use DescriptorPool to construct your own descriptors.
+class LIBPROTOBUF_EXPORT FieldDescriptor {
+ public:
+  // Identifies a field type.  0 is reserved for errors.  The order is weird
+  // for historical reasons.  Types 12 and up are new in proto2.
+  enum Type {
+    TYPE_DOUBLE         = 1,   // double, exactly eight bytes on the wire.
+    TYPE_FLOAT          = 2,   // float, exactly four bytes on the wire.
+    TYPE_INT64          = 3,   // int64, varint on the wire.  Negative numbers
+                               // take 10 bytes.  Use TYPE_SINT64 if negative
+                               // values are likely.
+    TYPE_UINT64         = 4,   // uint64, varint on the wire.
+    TYPE_INT32          = 5,   // int32, varint on the wire.  Negative numbers
+                               // take 10 bytes.  Use TYPE_SINT32 if negative
+                               // values are likely.
+    TYPE_FIXED64        = 6,   // uint64, exactly eight bytes on the wire.
+    TYPE_FIXED32        = 7,   // uint32, exactly four bytes on the wire.
+    TYPE_BOOL           = 8,   // bool, varint on the wire.
+    TYPE_STRING         = 9,   // UTF-8 text.
+    TYPE_GROUP          = 10,  // Tag-delimited message.  Deprecated.
+    TYPE_MESSAGE        = 11,  // Length-delimited message.
+
+    TYPE_BYTES          = 12,  // Arbitrary byte array.
+    TYPE_UINT32         = 13,  // uint32, varint on the wire
+    TYPE_ENUM           = 14,  // Enum, varint on the wire
+    TYPE_SFIXED32       = 15,  // int32, exactly four bytes on the wire
+    TYPE_SFIXED64       = 16,  // int64, exactly eight bytes on the wire
+    TYPE_SINT32         = 17,  // int32, ZigZag-encoded varint on the wire
+    TYPE_SINT64         = 18,  // int64, ZigZag-encoded varint on the wire
+
+    MAX_TYPE            = 18,  // Constant useful for defining lookup tables
+                               // indexed by Type.
+  };
+
+  // Specifies the C++ data type used to represent the field.  There is a
+  // fixed mapping from Type to CppType where each Type maps to exactly one
+  // CppType.  0 is reserved for errors.
+  enum CppType {
+    CPPTYPE_INT32       = 1,     // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32
+    CPPTYPE_INT64       = 2,     // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64
+    CPPTYPE_UINT32      = 3,     // TYPE_UINT32, TYPE_FIXED32
+    CPPTYPE_UINT64      = 4,     // TYPE_UINT64, TYPE_FIXED64
+    CPPTYPE_DOUBLE      = 5,     // TYPE_DOUBLE
+    CPPTYPE_FLOAT       = 6,     // TYPE_FLOAT
+    CPPTYPE_BOOL        = 7,     // TYPE_BOOL
+    CPPTYPE_ENUM        = 8,     // TYPE_ENUM
+    CPPTYPE_STRING      = 9,     // TYPE_STRING, TYPE_BYTES
+    CPPTYPE_MESSAGE     = 10,    // TYPE_MESSAGE, TYPE_GROUP
+
+    MAX_CPPTYPE         = 10,    // Constant useful for defining lookup tables
+                                 // indexed by CppType.
+  };
+
+  // Identifies whether the field is optional, required, or repeated.  0 is
+  // reserved for errors.
+  enum Label {
+    LABEL_OPTIONAL      = 1,    // optional
+    LABEL_REQUIRED      = 2,    // required
+    LABEL_REPEATED      = 3,    // repeated
+
+    MAX_LABEL           = 3,    // Constant useful for defining lookup tables
+                                // indexed by Label.
+  };
+
+  // Valid field numbers are positive integers up to kMaxNumber.
+  static const int kMaxNumber = (1 << 29) - 1;
+
+  // First field number reserved for the protocol buffer library implementation.
+  // Users may not declare fields that use reserved numbers.
+  static const int kFirstReservedNumber = 19000;
+  // Last field number reserved for the protocol buffer library implementation.
+  // Users may not declare fields that use reserved numbers.
+  static const int kLastReservedNumber  = 19999;
+
+  const string& name() const;        // Name of this field within the message.
+  const string& full_name() const;   // Fully-qualified name of the field.
+  const FileDescriptor* file() const;// File in which this field was defined.
+  bool is_extension() const;         // Is this an extension field?
+  int number() const;                // Declared tag number.
+
+  Type type() const;                 // Declared type of this field.
+  CppType cpp_type() const;          // C++ type of this field.
+  Label label() const;               // optional/required/repeated
+
+  bool is_required() const;      // shorthand for label() == LABEL_REQUIRED
+  bool is_optional() const;      // shorthand for label() == LABEL_OPTIONAL
+  bool is_repeated() const;      // shorthand for label() == LABEL_REPEATED
+
+  // Index of this field within the message's field array, or the file or
+  // extension scope's extensions array.
+  int index() const;
+
+  // Does this field have an explicitly-declared default value?
+  bool has_default_value() const;
+
+  // Get the field default value if cpp_type() == CPPTYPE_INT32.  If no
+  // explicit default was defined, the default is 0.
+  int32 default_value_int32() const;
+  // Get the field default value if cpp_type() == CPPTYPE_INT64.  If no
+  // explicit default was defined, the default is 0.
+  int64 default_value_int64() const;
+  // Get the field default value if cpp_type() == CPPTYPE_UINT32.  If no
+  // explicit default was defined, the default is 0.
+  uint32 default_value_uint32() const;
+  // Get the field default value if cpp_type() == CPPTYPE_UINT64.  If no
+  // explicit default was defined, the default is 0.
+  uint64 default_value_uint64() const;
+  // Get the field default value if cpp_type() == CPPTYPE_FLOAT.  If no
+  // explicit default was defined, the default is 0.0.
+  float default_value_float() const;
+  // Get the field default value if cpp_type() == CPPTYPE_DOUBLE.  If no
+  // explicit default was defined, the default is 0.0.
+  double default_value_double() const;
+  // Get the field default value if cpp_type() == CPPTYPE_BOOL.  If no
+  // explicit default was defined, the default is false.
+  bool default_value_bool() const;
+  // Get the field default value if cpp_type() == CPPTYPE_ENUM.  If no
+  // explicit default was defined, the default is the first value defined
+  // in the enum type (all enum types are required to have at least one value).
+  // This never returns NULL.
+  const EnumValueDescriptor* default_value_enum() const;
+  // Get the field default value if cpp_type() == CPPTYPE_STRING.  If no
+  // explicit default was defined, the default is the empty string.
+  const string& default_value_string() const;
+
+  // The Descriptor for the message of which this is a field.  For extensions,
+  // this is the extended type.  Never NULL.
+  const Descriptor* containing_type() const;
+
+  // An extension may be declared within the scope of another message.  If this
+  // field is an extension (is_extension() is true), then extension_scope()
+  // returns that message, or NULL if the extension was declared at global
+  // scope.  If this is not an extension, extension_scope() is undefined (may
+  // assert-fail).
+  const Descriptor* extension_scope() const;
+
+  // If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the
+  // message or the group type.  Otherwise, undefined.
+  const Descriptor* message_type() const;
+  // If type is TYPE_ENUM, returns a descriptor for the enum.  Otherwise,
+  // undefined.
+  const EnumDescriptor* enum_type() const;
+
+  // EXPERIMENTAL; DO NOT USE.
+  // If this field is a map field, experimental_map_key() is the field
+  // that is the key for this map.
+  // experimental_map_key()->containing_type() is the same as message_type().
+  const FieldDescriptor* experimental_map_key() const;
+
+  // Get the FieldOptions for this field.  This includes things listed in
+  // square brackets after the field definition.  E.g., the field:
+  //   optional string text = 1 [ctype=CORD];
+  // has the "ctype" option set.  FieldOptions is actually a protocol message,
+  // which makes it easier to extend.
+  const FieldOptions& options() const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(FieldDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+ private:
+  // See Descriptor::DebugString().
+  void DebugString(int depth, string *contents) const;
+
+  // formats the default value appropriately and returns it as a string.
+  // Must have a default value to call this. If quote_string_type is true, then
+  // types of CPPTYPE_STRING whill be surrounded by quotes and CEscaped.
+  string DefaultValueAsString(bool quote_string_type) const;
+
+  const string* name_;
+  const string* full_name_;
+  const FileDescriptor* file_;
+  int number_;
+  Type type_;
+  Label label_;
+  bool is_extension_;
+  const Descriptor* containing_type_;
+  const Descriptor* extension_scope_;
+  const Descriptor* message_type_;
+  const EnumDescriptor* enum_type_;
+  const FieldDescriptor* experimental_map_key_;
+  const FieldOptions* options_;
+
+  bool has_default_value_;
+  union {
+    int32  default_value_int32_;
+    int64  default_value_int64_;
+    uint32 default_value_uint32_;
+    uint64 default_value_uint64_;
+    float  default_value_float_;
+    double default_value_double_;
+    bool   default_value_bool_;
+
+    const EnumValueDescriptor* default_value_enum_;
+    const string* default_value_string_;
+  };
+
+  static const CppType kTypeToCppTypeMap[MAX_TYPE + 1];
+
+  static const char * const kTypeToName[MAX_TYPE + 1];
+
+  static const char * const kLabelToName[MAX_LABEL + 1];
+
+  // Must be constructed using DescriptorPool.
+  FieldDescriptor() {}
+  friend class DescriptorBuilder;
+  friend class FileDescriptor;
+  friend class Descriptor;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor);
+};
+
+// Describes an enum type defined in a .proto file.  To get the EnumDescriptor
+// for a generated enum type, call TypeName_descriptor().  Use DescriptorPool
+// to construct your own descriptors.
+class LIBPROTOBUF_EXPORT EnumDescriptor {
+ public:
+  // The name of this enum type in the containing scope.
+  const string& name() const;
+
+  // The fully-qualified name of the enum type, scope delimited by periods.
+  const string& full_name() const;
+
+  // Index of this enum within the file or containing message's enum array.
+  int index() const;
+
+  // The .proto file in which this enum type was defined.  Never NULL.
+  const FileDescriptor* file() const;
+
+  // The number of values for this EnumDescriptor.  Guaranteed to be greater
+  // than zero.
+  int value_count() const;
+  // Gets a value by index, where 0 <= index < value_count().
+  const EnumValueDescriptor* value(int index) const;
+
+  // Looks up a value by name.  Returns NULL if no such value exists.
+  const EnumValueDescriptor* FindValueByName(const string& name) const;
+  // Looks up a value by number.  Returns NULL if no such value exists.  If
+  // multiple values have this number, the first one defined is returned.
+  const EnumValueDescriptor* FindValueByNumber(int number) const;
+
+  // If this enum type is nested in a message type, this is that message type.
+  // Otherwise, NULL.
+  const Descriptor* containing_type() const;
+
+  // Get options for this enum type.  These are specified in the .proto
+  // file by placing lines like "option foo = 1234;" in the enum definition.
+  // The exact set of known options is defined by EnumOptions in
+  // google/protobuf/descriptor.proto.
+  const EnumOptions& options() const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(EnumDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+ private:
+  // See Descriptor::DebugString().
+  void DebugString(int depth, string *contents) const;
+
+  const string* name_;
+  const string* full_name_;
+  const FileDescriptor* file_;
+  int value_count_;
+  EnumValueDescriptor* values_;
+  const Descriptor* containing_type_;
+  const EnumOptions* options_;
+
+  // Must be constructed using DescriptorPool.
+  EnumDescriptor() {}
+  friend class DescriptorBuilder;
+  friend class Descriptor;
+  friend class EnumValueDescriptor;
+  friend class FileDescriptor;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor);
+};
+
+// Describes an individual enum constant of a particular type.  To get the
+// EnumValueDescriptor for a given enum value, first get the EnumDescriptor
+// for its type, then use EnumDescriptor::FindValueByName() or
+// EnumDescriptor::FindValueByNumber().  Use DescriptorPool to construct
+// your own descriptors.
+class LIBPROTOBUF_EXPORT EnumValueDescriptor {
+ public:
+  const string& name() const;  // Name of this enum constant.
+  int index() const;           // Index within the enums's Descriptor.
+  int number() const;          // Numeric value of this enum constant.
+
+  // The full_name of an enum value is a sibling symbol of the enum type.
+  // e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually
+  // "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT
+  // "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32".  This is to conform
+  // with C++ scoping rules for enums.
+  const string& full_name() const;
+
+  // The type of this value.  Never NULL.
+  const EnumDescriptor* type() const;
+
+  // Get options for this enum value.  These are specified in the .proto
+  // file by adding text like "[foo = 1234]" after an enum value definition.
+  // The exact set of known options is defined by EnumValueOptions in
+  // google/protobuf/descriptor.proto.
+  const EnumValueOptions& options() const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(EnumValueDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+ private:
+  // See Descriptor::DebugString().
+  void DebugString(int depth, string *contents) const;
+
+  const string* name_;
+  const string* full_name_;
+  int number_;
+  const EnumDescriptor* type_;
+  const EnumValueOptions* options_;
+
+  // Must be constructed using DescriptorPool.
+  EnumValueDescriptor() {}
+  friend class DescriptorBuilder;
+  friend class EnumDescriptor;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor);
+};
+
+// Describes an RPC service.  To get the ServiceDescriptor for a service,
+// call Service::GetDescriptor().  Generated service classes also have a
+// static method called descriptor() which returns the type's
+// ServiceDescriptor.  Use DescriptorPool to construct your own descriptors.
+class LIBPROTOBUF_EXPORT ServiceDescriptor {
+ public:
+  // The name of the service, not including its containing scope.
+  const string& name() const;
+  // The fully-qualified name of the service, scope delimited by periods.
+  const string& full_name() const;
+  // Index of this service within the file's services array.
+  int index() const;
+
+  // The .proto file in which this service was defined.  Never NULL.
+  const FileDescriptor* file() const;
+
+  // Get options for this service type.  These are specified in the .proto
+  // file by placing lines like "option foo = 1234;" in the service definition.
+  // The exact set of known options is defined by ServiceOptions in
+  // google/protobuf/descriptor.proto.
+  const ServiceOptions& options() const;
+
+  // The number of methods this service defines.
+  int method_count() const;
+  // Gets a MethodDescriptor by index, where 0 <= index < method_count().
+  const MethodDescriptor* method(int index) const;
+
+  // Look up a MethodDescriptor by name.
+  const MethodDescriptor* FindMethodByName(const string& name) const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(ServiceDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+ private:
+  // See Descriptor::DebugString().
+  void DebugString(string *contents) const;
+
+  const string* name_;
+  const string* full_name_;
+  const FileDescriptor* file_;
+  const ServiceOptions* options_;
+  int method_count_;
+  MethodDescriptor* methods_;
+
+  // Must be constructed using DescriptorPool.
+  ServiceDescriptor() {}
+  friend class DescriptorBuilder;
+  friend class FileDescriptor;
+  friend class MethodDescriptor;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceDescriptor);
+};
+
+// Describes an individual service method.  To obtain a MethodDescriptor given
+// a service, first get its ServiceDescriptor, then call
+// ServiceDescriptor::FindMethodByName().  Use DescriptorPool to construct your
+// own descriptors.
+class LIBPROTOBUF_EXPORT MethodDescriptor {
+ public:
+  // Name of this method, not including containing scope.
+  const string& name() const;
+  // The fully-qualified name of the method, scope delimited by periods.
+  const string& full_name() const;
+  // Index within the service's Descriptor.
+  int index() const;
+
+  // Gets the service to which this method belongs.  Never NULL.
+  const ServiceDescriptor* service() const;
+
+  // Gets the type of protocol message which this method accepts as input.
+  const Descriptor* input_type() const;
+  // Gets the type of protocol message which this message produces as output.
+  const Descriptor* output_type() const;
+
+  // Get options for this method.  These are specified in the .proto
+  // file by placing lines like "option foo = 1234;" in curly-braces after
+  // a method declaration.  The exact set of known options is defined by
+  // MethodOptions in google/protobuf/descriptor.proto.
+  const MethodOptions& options() const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(MethodDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+ private:
+  // See Descriptor::DebugString().
+  void DebugString(int depth, string *contents) const;
+
+  const string* name_;
+  const string* full_name_;
+  const ServiceDescriptor* service_;
+  const Descriptor* input_type_;
+  const Descriptor* output_type_;
+  const MethodOptions* options_;
+
+  // Must be constructed using DescriptorPool.
+  MethodDescriptor() {}
+  friend class DescriptorBuilder;
+  friend class ServiceDescriptor;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor);
+};
+
+// Describes a whole .proto file.  To get the FileDescriptor for a compiled-in
+// file, get the descriptor for something defined in that file and call
+// descriptor->file().  Use DescriptorPool to construct your own descriptors.
+class LIBPROTOBUF_EXPORT FileDescriptor {
+ public:
+  // The filename, relative to the source tree.
+  // e.g. "google/protobuf/descriptor.proto"
+  const string& name() const;
+
+  // The package, e.g. "google.protobuf.compiler".
+  const string& package() const;
+
+  // The DescriptorPool in which this FileDescriptor and all its contents were
+  // allocated.  Never NULL.
+  const DescriptorPool* pool() const;
+
+  // The number of files imported by this one.
+  int dependency_count() const;
+  // Gets an imported file by index, where 0 <= index < dependency_count().
+  const FileDescriptor* dependency(int index) const;
+
+  // Number of top-level message types defined in this file.  (This does not
+  // include nested types.)
+  int message_type_count() const;
+  // Gets a top-level message type, where 0 <= index < message_type_count().
+  const Descriptor* message_type(int index) const;
+
+  // Number of top-level enum types defined in this file.  (This does not
+  // include nested types.)
+  int enum_type_count() const;
+  // Gets a top-level enum type, where 0 <= index < enum_type_count().
+  const EnumDescriptor* enum_type(int index) const;
+
+  // Number of services defined in this file.
+  int service_count() const;
+  // Gets a service, where 0 <= index < service_count().
+  const ServiceDescriptor* service(int index) const;
+
+  // Number of extensions defined at file scope.  (This does not include
+  // extensions nested within message types.)
+  int extension_count() const;
+  // Gets an extension's descriptor, where 0 <= index < extension_count().
+  const FieldDescriptor* extension(int index) const;
+
+  // Get options for this file.  These are specified in the .proto
+  // file by placing lines like "option foo = 1234;" at the top level, outside
+  // of any other definitions.  The exact set of known options is defined by
+  // FileOptions in google/protobuf/descriptor.proto.
+  const FileOptions& options() const;
+
+  // Find a top-level message type by name.  Returns NULL if not found.
+  const Descriptor* FindMessageTypeByName(const string& name) const;
+  // Find a top-level enum type by name.  Returns NULL if not found.
+  const EnumDescriptor* FindEnumTypeByName(const string& name) const;
+  // Find an enum value defined in any top-level enum by name.  Returns NULL if
+  // not found.
+  const EnumValueDescriptor* FindEnumValueByName(const string& name) const;
+  // Find a service definition by name.  Returns NULL if not found.
+  const ServiceDescriptor* FindServiceByName(const string& name) const;
+  // Find a top-level extension definition by name.  Returns NULL if not found.
+  const FieldDescriptor* FindExtensionByName(const string& name) const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(FileDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+ private:
+  const string* name_;
+  const string* package_;
+  const DescriptorPool* pool_;
+  int dependency_count_;
+  const FileDescriptor** dependencies_;
+  int message_type_count_;
+  Descriptor* message_types_;
+  int enum_type_count_;
+  EnumDescriptor* enum_types_;
+  int service_count_;
+  ServiceDescriptor* services_;
+  int extension_count_;
+  FieldDescriptor* extensions_;
+  const FileOptions* options_;
+
+  FileDescriptor() {}
+  friend class DescriptorBuilder;
+  friend class Descriptor;
+  friend class FieldDescriptor;
+  friend class EnumDescriptor;
+  friend class ServiceDescriptor;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor);
+};
+
+// ===================================================================
+
+// Used to construct descriptors.
+//
+// Normally you won't want to build your own descriptors.  Message classes
+// constructed by the protocol compiler will provide them for you.  However,
+// if you are implementing Message on your own, or if you are writing a
+// program which can operate on totally arbitrary types and needs to load
+// them from some sort of database, you might need to.
+//
+// Since Descriptors are composed of a whole lot of cross-linked bits of
+// data that would be a pain to put together manually, the
+// DescriptorPool class is provided to make the process easier.  It can
+// take a FileDescriptorProto (defined in descriptor.proto), validate it,
+// and convert it to a set of nicely cross-linked Descriptors.
+//
+// DescriptorPool also helps with memory management.  Descriptors are
+// composed of many objects containing static data and pointers to each
+// other.  In all likelihood, when it comes time to delete this data,
+// you'll want to delete it all at once.  In fact, it is not uncommon to
+// have a whole pool of descriptors all cross-linked with each other which
+// you wish to delete all at once.  This class represents such a pool, and
+// handles the memory management for you.
+//
+// You can also search for descriptors within a DescriptorPool by name, and
+// extensions by number.
+class LIBPROTOBUF_EXPORT DescriptorPool {
+ public:
+  // Create a normal, empty DescriptorPool.
+  DescriptorPool();
+
+  // Constructs a DescriptorPool that, when it can't find something among the
+  // descriptors already in the pool, looks for it in the given
+  // DescriptorDatabase.
+  // Notes:
+  // - If a DescriptorPool is constructed this way, its BuildFile*() methods
+  //   must not be called (they will assert-fail).  The only way to populate
+  //   the pool with descriptors is to call the Find*By*() methods.
+  // - The Find*By*() methods may block the calling thread if the
+  //   DescriptorDatabase blocks.  This in turn means that parsing messages
+  //   may block if they need to look up extensions.
+  // - The Find*By*() methods will use mutexes for thread-safety, thus making
+  //   them slower even when they don't have to fall back to the database.
+  //   In fact, even the Find*By*() methods of descriptor objects owned by
+  //   this pool will be slower, since they will have to obtain locks too.
+  // - An ErrorCollector may optionally be given to collect validation errors
+  //   in files loaded from the database.  If not given, errors will be printed
+  //   to GOOGLE_LOG(ERROR).  Remember that files are built on-demand, so this
+  //   ErrorCollector may be called from any thread that calls one of the
+  //   Find*By*() methods.
+  class ErrorCollector;
+  explicit DescriptorPool(DescriptorDatabase* fallback_database,
+                          ErrorCollector* error_collector = NULL);
+
+  ~DescriptorPool();
+
+  // Get a pointer to the generated pool.  Generated protocol message classes
+  // which are compiled into the binary will allocate their descriptors in
+  // this pool.  Do not add your own descriptors to this pool.
+  static const DescriptorPool* generated_pool();
+
+  // Find a FileDescriptor in the pool by file name.  Returns NULL if not
+  // found.
+  const FileDescriptor* FindFileByName(const string& name) const;
+
+  // Find the FileDescriptor in the pool which defines the given symbol.
+  // If any of the Find*ByName() methods below would succeed, then this is
+  // equivalent to calling that method and calling the result's file() method.
+  // Otherwise this returns NULL.
+  const FileDescriptor* FindFileContainingSymbol(
+      const string& symbol_name) const;
+
+  // Looking up descriptors ------------------------------------------
+  // These find descriptors by fully-qualified name.  These will find both
+  // top-level descriptors and nested descriptors.  They return NULL if not
+  // found.
+
+  const Descriptor* FindMessageTypeByName(const string& name) const;
+  const FieldDescriptor* FindFieldByName(const string& name) const;
+  const FieldDescriptor* FindExtensionByName(const string& name) const;
+  const EnumDescriptor* FindEnumTypeByName(const string& name) const;
+  const EnumValueDescriptor* FindEnumValueByName(const string& name) const;
+  const ServiceDescriptor* FindServiceByName(const string& name) const;
+  const MethodDescriptor* FindMethodByName(const string& name) const;
+
+  // Finds an extension of the given type by number.  The extendee must be
+  // a member of this DescriptorPool or one of its underlays.
+  const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee,
+                                               int number) const;
+
+  // Building descriptors --------------------------------------------
+
+  // When converting a FileDescriptorProto to a FileDescriptor, various
+  // errors might be detected in the input.  The caller may handle these
+  // programmatically by implementing an ErrorCollector.
+  class LIBPROTOBUF_EXPORT ErrorCollector {
+   public:
+    inline ErrorCollector() {}
+    virtual ~ErrorCollector();
+
+    // These constants specify what exact part of the construct is broken.
+    // This is useful e.g. for mapping the error back to an exact location
+    // in a .proto file.
+    enum ErrorLocation {
+      NAME,              // the symbol name, or the package name for files
+      NUMBER,            // field or extension range number
+      TYPE,              // field type
+      EXTENDEE,          // field extendee
+      DEFAULT_VALUE,     // field default value
+      INPUT_TYPE,        // method input type
+      OUTPUT_TYPE,       // method output type
+      OTHER              // some other problem
+    };
+
+    // Reports an error in the FileDescriptorProto.
+    virtual void AddError(
+      const string& filename,      // File name in which the error occurred.
+      const string& element_name,  // Full name of the erroneous element.
+      const Message* descriptor,   // Descriptor of the erroneous element.
+      ErrorLocation location,      // One of the location constants, above.
+      const string& message        // Human-readable error message.
+      ) = 0;
+
+   private:
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
+  };
+
+  // Convert the FileDescriptorProto to real descriptors and place them in
+  // this DescriptorPool.  All dependencies of the file must already be in
+  // the pool.  Returns the resulting FileDescriptor, or NULL if there were
+  // problems with the input (e.g. the message was invalid, or dependencies
+  // were missing).  Details about the errors are written to GOOGLE_LOG(ERROR).
+  const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
+
+  // Same as BuildFile() except errors are sent to the given ErrorCollector.
+  const FileDescriptor* BuildFileCollectingErrors(
+    const FileDescriptorProto& proto,
+    ErrorCollector* error_collector);
+
+  // Internal stuff --------------------------------------------------
+  // These methods MUST NOT be called from outside the proto2 library.
+  // These methods may contain hidden pitfalls and may be removed in a
+  // future library version.
+
+  // DEPRECATED:  Use of underlays can lead to many subtle gotchas.  Instead,
+  //   try to formulate what you want to do in terms of DescriptorDatabases.
+  //   This constructor will be removed soon.
+  //
+  // Create a DescriptorPool which is overlaid on top of some other pool.
+  // If you search for a descriptor in the overlay and it is not found, the
+  // underlay will be searched as a backup.  If the underlay has its own
+  // underlay, that will be searched next, and so on.  This also means that
+  // files built in the overlay will be cross-linked with the underlay's
+  // descriptors if necessary.  The underlay remains property of the caller;
+  // it must remain valid for the lifetime of the newly-constructed pool.
+  //
+  // Example:  Say you want to parse a .proto file at runtime in order to use
+  // its type with a DynamicMessage.  Say this .proto file has dependencies,
+  // but you know that all the dependencies will be things that are already
+  // compiled into the binary.  For ease of use, you'd like to load the types
+  // right out of generated_pool() rather than have to parse redundant copies
+  // of all these .protos and runtime.  But, you don't want to add the parsed
+  // types directly into generated_pool(): this is not allowed, and would be
+  // bad design anyway.  So, instead, you could use generated_pool() as an
+  // underlay for a new DescriptorPool in which you add only the new file.
+  explicit DescriptorPool(const DescriptorPool* underlay);
+
+  // Called by generated classes at init time.  Do NOT call this in your
+  // own code!
+  const FileDescriptor* InternalBuildGeneratedFile(
+    const void* data, int size);
+
+  // For internal use only:  Gets a non-const pointer to the generated pool.
+  // This is called at static-initialization time only, so thread-safety is
+  // not a concern.  If both an underlay and a fallback database are present,
+  // the fallback database takes precedence.
+  static DescriptorPool* internal_generated_pool();
+
+  // For internal use only:  Changes the behavior of BuildFile() such that it
+  // allows the file to make reference to message types declared in other files
+  // which it did not officially declare as dependencies.
+  void InternalDontEnforceDependencies();
+
+  // For internal use only.
+  void internal_set_underlay(const DescriptorPool* underlay) {
+    underlay_ = underlay;
+  }
+
+ private:
+  friend class Descriptor;
+  friend class FieldDescriptor;
+  friend class EnumDescriptor;
+  friend class ServiceDescriptor;
+  friend class FileDescriptor;
+  friend class DescriptorBuilder;
+
+  // Tries to find something in the fallback database and link in the
+  // corresponding proto file.  Returns true if successful, in which case
+  // the caller should search for the thing again.  These are declared
+  // const because they are called by (semantically) const methods.
+  bool TryFindFileInFallbackDatabase(const string& name) const;
+  bool TryFindSymbolInFallbackDatabase(const string& name) const;
+  bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type,
+                                          int field_number) const;
+
+  // Like BuildFile() but called internally when the file has been loaded from
+  // fallback_database_.  Declared const because it is called by (semantically)
+  // const methods.
+  const FileDescriptor* BuildFileFromDatabase(
+    const FileDescriptorProto& proto) const;
+
+  // If fallback_database_ is NULL, this is NULL.  Otherwise, this is a mutex
+  // which must be locked while accessing tables_.
+  Mutex* mutex_;
+
+  // See constructor.
+  DescriptorDatabase* fallback_database_;
+  ErrorCollector* default_error_collector_;
+  const DescriptorPool* underlay_;
+
+  // This class contains a lot of hash maps with complicated types that
+  // we'd like to keep out of the header.
+  class Tables;
+  scoped_ptr<Tables> tables_;
+
+  bool enforce_dependencies_;
+
+  // See InternalBuildGeneratedFile().
+  const void* last_internal_build_generated_file_call_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool);
+};
+
+// inline methods ====================================================
+
+// These macros makes this repetitive code more readable.
+#define PROTOBUF_DEFINE_ACCESSOR(CLASS, FIELD, TYPE) \
+  inline TYPE CLASS::FIELD() const { return FIELD##_; }
+
+// Strings fields are stored as pointers but returned as const references.
+#define PROTOBUF_DEFINE_STRING_ACCESSOR(CLASS, FIELD) \
+  inline const string& CLASS::FIELD() const { return *FIELD##_; }
+
+// Arrays take an index parameter, obviously.
+#define PROTOBUF_DEFINE_ARRAY_ACCESSOR(CLASS, FIELD, TYPE) \
+  inline TYPE CLASS::FIELD(int index) const { return FIELD##s_ + index; }
+
+#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \
+  inline const TYPE& CLASS::options() const { return *options_; }
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*)
+
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int)
+
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, field, const FieldDescriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, nested_type, const Descriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, enum_type, const EnumDescriptor*)
+
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_range_count, int)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_count, int)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range,
+                               const Descriptor::ExtensionRange*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension,
+                               const FieldDescriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions);
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, type, FieldDescriptor::Type)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, experimental_map_key,
+                         const FieldDescriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions);
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32 , int32 )
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64 , int64 )
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32, uint32)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64, uint64)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float , float )
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool  , bool  )
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_enum,
+                         const EnumValueDescriptor*)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string)
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value,
+                               const EnumValueDescriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions);
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int)
+PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions);
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method,
+                               const MethodDescriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions);
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions);
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions);
+
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, service,
+                               const ServiceDescriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension,
+                               const FieldDescriptor*)
+
+#undef PROTOBUF_DEFINE_ACCESSOR
+#undef PROTOBUF_DEFINE_STRING_ACCESSOR
+#undef PROTOBUF_DEFINE_ARRAY_ACCESSOR
+
+// A few accessors differ from the macros...
+
+inline bool FieldDescriptor::is_required() const {
+  return label() == LABEL_REQUIRED;
+}
+
+inline bool FieldDescriptor::is_optional() const {
+  return label() == LABEL_OPTIONAL;
+}
+
+inline bool FieldDescriptor::is_repeated() const {
+  return label() == LABEL_REPEATED;
+}
+
+// To save space, index() is computed by looking at the descriptor's position
+// in the parent's array of children.
+inline int FieldDescriptor::index() const {
+  if (!is_extension_) {
+    return this - containing_type_->fields_;
+  } else if (extension_scope_ != NULL) {
+    return this - extension_scope_->extensions_;
+  } else {
+    return this - file_->extensions_;
+  }
+}
+
+inline int Descriptor::index() const {
+  if (containing_type_ == NULL) {
+    return this - file_->message_types_;
+  } else {
+    return this - containing_type_->nested_types_;
+  }
+}
+
+inline int EnumDescriptor::index() const {
+  if (containing_type_ == NULL) {
+    return this - file_->enum_types_;
+  } else {
+    return this - containing_type_->enum_types_;
+  }
+}
+
+inline int EnumValueDescriptor::index() const {
+  return this - type_->values_;
+}
+
+inline int ServiceDescriptor::index() const {
+  return this - file_->services_;
+}
+
+inline int MethodDescriptor::index() const {
+  return this - service_->methods_;
+}
+
+inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const {
+  return kTypeToCppTypeMap[type_];
+}
+
+inline const FileDescriptor* FileDescriptor::dependency(int index) const {
+  return dependencies_[index];
+}
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_DESCRIPTOR_H__
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
new file mode 100644
index 0000000..836d141
--- /dev/null
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -0,0 +1,3935 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+
+#include "google/protobuf/descriptor.pb.h"
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format_inl.h>
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+const ::google::protobuf::Descriptor* FileDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* DescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* FieldDescriptorProto_descriptor_ = 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::Descriptor* EnumValueDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* ServiceDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* MethodDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* FileOptions_descriptor_ = NULL;
+const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* MessageOptions_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* FieldOptions_descriptor_ = NULL;
+const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* EnumValueOptions_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* ServiceOptions_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* MethodOptions_descriptor_ = NULL;
+
+}  // namespace
+
+
+void proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto() {
+  static bool already_here = false;
+  if (already_here) return;
+  already_here = true;
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+  ::google::protobuf::DescriptorPool* pool =
+    ::google::protobuf::DescriptorPool::internal_generated_pool();
+
+  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);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    FileDescriptorProto_descriptor_, &FileDescriptorProto::default_instance());
+  DescriptorProto_descriptor_ = file->message_type(1);
+  DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0);
+  ::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_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);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    EnumDescriptorProto_descriptor_, &EnumDescriptorProto::default_instance());
+  EnumValueDescriptorProto_descriptor_ = file->message_type(4);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    EnumValueDescriptorProto_descriptor_, &EnumValueDescriptorProto::default_instance());
+  ServiceDescriptorProto_descriptor_ = file->message_type(5);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    ServiceDescriptorProto_descriptor_, &ServiceDescriptorProto::default_instance());
+  MethodDescriptorProto_descriptor_ = file->message_type(6);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    MethodDescriptorProto_descriptor_, &MethodDescriptorProto::default_instance());
+  FileOptions_descriptor_ = file->message_type(7);
+  FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    FileOptions_descriptor_, &FileOptions::default_instance());
+  MessageOptions_descriptor_ = file->message_type(8);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    MessageOptions_descriptor_, &MessageOptions::default_instance());
+  FieldOptions_descriptor_ = file->message_type(9);
+  FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    FieldOptions_descriptor_, &FieldOptions::default_instance());
+  EnumOptions_descriptor_ = file->message_type(10);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    EnumOptions_descriptor_, &EnumOptions::default_instance());
+  EnumValueOptions_descriptor_ = file->message_type(11);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    EnumValueOptions_descriptor_, &EnumValueOptions::default_instance());
+  ServiceOptions_descriptor_ = file->message_type(12);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    ServiceOptions_descriptor_, &ServiceOptions::default_instance());
+  MethodOptions_descriptor_ = file->message_type(13);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    MethodOptions_descriptor_, &MethodOptions::default_instance());
+}
+
+// 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();
+  }
+} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_;
+
+
+// ===================================================================
+
+const FileDescriptorProto FileDescriptorProto::default_instance_;
+
+const ::std::string FileDescriptorProto::_default_name_;
+const ::std::string FileDescriptorProto::_default_package_;
+
+
+
+
+
+
+const int FileDescriptorProto::_offsets_[8] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, message_type_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, enum_type_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, service_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, extension_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, options_),
+};
+
+FileDescriptorProto::FileDescriptorProto()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    package_(const_cast< ::std::string*>(&_default_package_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+    options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance());
+  }
+}
+
+FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    package_(const_cast< ::std::string*>(&_default_package_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+FileDescriptorProto::~FileDescriptorProto() {
+  if (name_ != &_default_name_) {
+    delete name_;
+  }
+  if (package_ != &_default_package_) {
+    delete package_;
+  }
+  if (this != &default_instance_) {
+    delete options_;
+  }
+}
+
+const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() {
+  if (FileDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return FileDescriptorProto_descriptor_;
+}
+
+FileDescriptorProto* FileDescriptorProto::New() const {
+  return new FileDescriptorProto;
+}
+
+void FileDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (_has_bit(0)) {
+      if (name_ != &_default_name_) {
+        name_->clear();
+      }
+    }
+    if (_has_bit(1)) {
+      if (package_ != &_default_package_) {
+        package_->clear();
+      }
+    }
+    if (_has_bit(7)) {
+      if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
+    }
+  }
+  dependency_.Clear();
+  message_type_.Clear();
+  enum_type_.Clear();
+  service_.Clear();
+  extension_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool FileDescriptorProto::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)) {
+      // optional string name = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name()));
+        if (input->ExpectTag(18)) goto parse_package;
+        break;
+      }
+      
+      // optional string package = 2;
+      case 2: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_package:
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_package()));
+        if (input->ExpectTag(26)) goto parse_dependency;
+        break;
+      }
+      
+      // repeated string dependency = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_dependency:
+        DO_(::google::protobuf::internal::WireFormat::ReadString(
+             input, add_dependency()));
+        if (input->ExpectTag(26)) goto parse_dependency;
+        if (input->ExpectTag(34)) goto parse_message_type;
+        break;
+      }
+      
+      // repeated .google.protobuf.DescriptorProto message_type = 4;
+      case 4: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_message_type:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_message_type()));
+        if (input->ExpectTag(34)) goto parse_message_type;
+        if (input->ExpectTag(42)) goto parse_enum_type;
+        break;
+      }
+      
+      // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+      case 5: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_enum_type:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_enum_type()));
+        if (input->ExpectTag(42)) goto parse_enum_type;
+        if (input->ExpectTag(50)) goto parse_service;
+        break;
+      }
+      
+      // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+      case 6: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_service:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_service()));
+        if (input->ExpectTag(50)) goto parse_service;
+        if (input->ExpectTag(58)) goto parse_extension;
+        break;
+      }
+      
+      // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+      case 7: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_extension:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_extension()));
+        if (input->ExpectTag(58)) goto parse_extension;
+        if (input->ExpectTag(66)) goto parse_options;
+        break;
+      }
+      
+      // optional .google.protobuf.FileOptions options = 8;
+      case 8: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_options:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, mutable_options()));
+        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 FileDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional string name = 1;
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output));
+  }
+  
+  // optional string package = 2;
+  if (_has_bit(1)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(2, this->package(), output));
+  }
+  
+  // repeated string dependency = 3;
+  for (int i = 0; i < dependency_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(3, this->dependency(i), output));
+  }
+  
+  // repeated .google.protobuf.DescriptorProto message_type = 4;
+  for (int i = 0; i < message_type_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->message_type(i), output));
+  }
+  
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+  for (int i = 0; i < enum_type_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(5, this->enum_type(i), output));
+  }
+  
+  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+  for (int i = 0; i < service_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(6, this->service(i), output));
+  }
+  
+  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+  for (int i = 0; i < extension_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(7, this->extension(i), output));
+  }
+  
+  // optional .google.protobuf.FileOptions options = 8;
+  if (_has_bit(7)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(8, this->options(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int FileDescriptorProto::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional string name = 1;
+    if (has_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->name());
+    }
+    
+    // optional string package = 2;
+    if (has_package()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->package());
+    }
+    
+    // optional .google.protobuf.FileOptions options = 8;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+          this->options());
+    }
+    
+  }
+  // repeated string dependency = 3;
+  total_size += 1 * dependency_size();
+  for (int i = 0; i < dependency_size(); i++) {
+    total_size += ::google::protobuf::internal::WireFormat::StringSize(
+      this->dependency(i));
+  }
+  
+  // repeated .google.protobuf.DescriptorProto message_type = 4;
+  total_size += 1 * message_type_size();
+  for (int i = 0; i < message_type_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->message_type(i));
+  }
+  
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+  total_size += 1 * enum_type_size();
+  for (int i = 0; i < enum_type_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->enum_type(i));
+  }
+  
+  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+  total_size += 1 * service_size();
+  for (int i = 0; i < service_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->service(i));
+  }
+  
+  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+  total_size += 1 * extension_size();
+  for (int i = 0; i < extension_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->extension(i));
+  }
+  
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const FileDescriptorProto* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorProto*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  dependency_.MergeFrom(from.dependency_);
+  message_type_.MergeFrom(from.message_type_);
+  enum_type_.MergeFrom(from.enum_type_);
+  service_.MergeFrom(from.service_);
+  extension_.MergeFrom(from.extension_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_name(from.name());
+    }
+    if (from._has_bit(1)) {
+      set_package(from.package());
+    }
+    if (from._has_bit(7)) {
+      mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FileDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool FileDescriptorProto::IsInitialized() const {
+  
+  return true;
+}
+
+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 DescriptorProto_ExtensionRange DescriptorProto_ExtensionRange::default_instance_;
+
+
+
+const int DescriptorProto_ExtensionRange::_offsets_[2] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_),
+};
+
+DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    start_(0),
+    end_(0) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+  }
+}
+
+DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    start_(0),
+    end_(0) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
+  if (this != &default_instance_) {
+  }
+}
+
+const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() {
+  if (DescriptorProto_ExtensionRange_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return DescriptorProto_ExtensionRange_descriptor_;
+}
+
+DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New() const {
+  return new DescriptorProto_ExtensionRange;
+}
+
+void DescriptorProto_ExtensionRange::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    start_ = 0;
+    end_ = 0;
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool DescriptorProto_ExtensionRange::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)) {
+      // optional int32 start = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+          goto handle_uninterpreted;
+        }
+        DO_(::google::protobuf::internal::WireFormat::ReadInt32(
+              input, &start_));
+        _set_bit(0);
+        if (input->ExpectTag(16)) goto parse_end;
+        break;
+      }
+      
+      // optional int32 end = 2;
+      case 2: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+          goto handle_uninterpreted;
+        }
+       parse_end:
+        DO_(::google::protobuf::internal::WireFormat::ReadInt32(
+              input, &end_));
+        _set_bit(1);
+        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 DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional int32 start = 1;
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteInt32(1, this->start(), output));
+  }
+  
+  // optional int32 end = 2;
+  if (_has_bit(1)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteInt32(2, this->end(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int DescriptorProto_ExtensionRange::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional int32 start = 1;
+    if (has_start()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::Int32Size(
+          this->start());
+    }
+    
+    // optional int32 end = 2;
+    if (has_end()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::Int32Size(
+          this->end());
+    }
+    
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const DescriptorProto_ExtensionRange* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto_ExtensionRange*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_start(from.start());
+    }
+    if (from._has_bit(1)) {
+      set_end(from.end());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void DescriptorProto_ExtensionRange::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool DescriptorProto_ExtensionRange::IsInitialized() const {
+  
+  return true;
+}
+
+const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::GetDescriptor() const {
+  return descriptor();
+}
+
+const ::google::protobuf::Message::Reflection*
+DescriptorProto_ExtensionRange::GetReflection() const {
+  return &_reflection_;
+}
+
+::google::protobuf::Message::Reflection* DescriptorProto_ExtensionRange::GetReflection() {
+  return &_reflection_;
+}
+
+// -------------------------------------------------------------------
+
+const DescriptorProto DescriptorProto::default_instance_;
+
+const ::std::string DescriptorProto::_default_name_;
+
+
+
+
+
+
+const int DescriptorProto::_offsets_[7] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, nested_type_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, enum_type_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_range_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, options_),
+};
+
+DescriptorProto::DescriptorProto()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+    options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance());
+  }
+}
+
+DescriptorProto::DescriptorProto(const DescriptorProto& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+DescriptorProto::~DescriptorProto() {
+  if (name_ != &_default_name_) {
+    delete name_;
+  }
+  if (this != &default_instance_) {
+    delete options_;
+  }
+}
+
+const ::google::protobuf::Descriptor* DescriptorProto::descriptor() {
+  if (DescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return DescriptorProto_descriptor_;
+}
+
+DescriptorProto* DescriptorProto::New() const {
+  return new DescriptorProto;
+}
+
+void DescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (_has_bit(0)) {
+      if (name_ != &_default_name_) {
+        name_->clear();
+      }
+    }
+    if (_has_bit(6)) {
+      if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
+    }
+  }
+  field_.Clear();
+  extension_.Clear();
+  nested_type_.Clear();
+  enum_type_.Clear();
+  extension_range_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool DescriptorProto::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)) {
+      // optional string name = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name()));
+        if (input->ExpectTag(18)) goto parse_field;
+        break;
+      }
+      
+      // repeated .google.protobuf.FieldDescriptorProto field = 2;
+      case 2: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_field:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_field()));
+        if (input->ExpectTag(18)) goto parse_field;
+        if (input->ExpectTag(26)) goto parse_nested_type;
+        break;
+      }
+      
+      // repeated .google.protobuf.DescriptorProto nested_type = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_nested_type:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_nested_type()));
+        if (input->ExpectTag(26)) goto parse_nested_type;
+        if (input->ExpectTag(34)) goto parse_enum_type;
+        break;
+      }
+      
+      // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+      case 4: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_enum_type:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_enum_type()));
+        if (input->ExpectTag(34)) goto parse_enum_type;
+        if (input->ExpectTag(42)) goto parse_extension_range;
+        break;
+      }
+      
+      // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+      case 5: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_extension_range:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_extension_range()));
+        if (input->ExpectTag(42)) goto parse_extension_range;
+        if (input->ExpectTag(50)) goto parse_extension;
+        break;
+      }
+      
+      // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+      case 6: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_extension:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_extension()));
+        if (input->ExpectTag(50)) goto parse_extension;
+        if (input->ExpectTag(58)) goto parse_options;
+        break;
+      }
+      
+      // optional .google.protobuf.MessageOptions options = 7;
+      case 7: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_options:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, mutable_options()));
+        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 DescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional string name = 1;
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output));
+  }
+  
+  // repeated .google.protobuf.FieldDescriptorProto field = 2;
+  for (int i = 0; i < field_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->field(i), output));
+  }
+  
+  // repeated .google.protobuf.DescriptorProto nested_type = 3;
+  for (int i = 0; i < nested_type_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->nested_type(i), output));
+  }
+  
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+  for (int i = 0; i < enum_type_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->enum_type(i), output));
+  }
+  
+  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+  for (int i = 0; i < extension_range_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(5, this->extension_range(i), output));
+  }
+  
+  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+  for (int i = 0; i < extension_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(6, this->extension(i), output));
+  }
+  
+  // optional .google.protobuf.MessageOptions options = 7;
+  if (_has_bit(6)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(7, this->options(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int DescriptorProto::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional string name = 1;
+    if (has_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->name());
+    }
+    
+    // optional .google.protobuf.MessageOptions options = 7;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+          this->options());
+    }
+    
+  }
+  // repeated .google.protobuf.FieldDescriptorProto field = 2;
+  total_size += 1 * field_size();
+  for (int i = 0; i < field_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->field(i));
+  }
+  
+  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+  total_size += 1 * extension_size();
+  for (int i = 0; i < extension_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->extension(i));
+  }
+  
+  // repeated .google.protobuf.DescriptorProto nested_type = 3;
+  total_size += 1 * nested_type_size();
+  for (int i = 0; i < nested_type_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->nested_type(i));
+  }
+  
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+  total_size += 1 * enum_type_size();
+  for (int i = 0; i < enum_type_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->enum_type(i));
+  }
+  
+  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+  total_size += 1 * extension_range_size();
+  for (int i = 0; i < extension_range_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->extension_range(i));
+  }
+  
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const DescriptorProto* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void DescriptorProto::MergeFrom(const DescriptorProto& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  field_.MergeFrom(from.field_);
+  extension_.MergeFrom(from.extension_);
+  nested_type_.MergeFrom(from.nested_type_);
+  enum_type_.MergeFrom(from.enum_type_);
+  extension_range_.MergeFrom(from.extension_range_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_name(from.name());
+    }
+    if (from._has_bit(6)) {
+      mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void DescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void DescriptorProto::CopyFrom(const DescriptorProto& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool DescriptorProto::IsInitialized() const {
+  
+  return true;
+}
+
+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::EnumDescriptor* FieldDescriptorProto_Type_descriptor() {
+  if (FieldDescriptorProto_Type_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return FieldDescriptorProto_Type_descriptor_;
+}
+bool FieldDescriptorProto_Type_IsValid(int value) {
+  switch(value) {
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+    case 16:
+    case 17:
+    case 18:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#ifndef _MSC_VER
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64;
+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();
+  return FieldDescriptorProto_Label_descriptor_;
+}
+bool FieldDescriptorProto_Label_IsValid(int value) {
+  switch(value) {
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#ifndef _MSC_VER
+const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL;
+const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED;
+const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED;
+const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
+const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
+#endif  // _MSC_VER
+const FieldDescriptorProto FieldDescriptorProto::default_instance_;
+
+const ::std::string FieldDescriptorProto::_default_name_;
+
+
+
+const ::std::string FieldDescriptorProto::_default_type_name_;
+const ::std::string FieldDescriptorProto::_default_extendee_;
+const ::std::string FieldDescriptorProto::_default_default_value_;
+
+const int FieldDescriptorProto::_offsets_[8] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, number_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, label_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_name_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, extendee_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, default_value_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, options_),
+};
+
+FieldDescriptorProto::FieldDescriptorProto()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    number_(0),
+    label_(1),
+    type_(1),
+    type_name_(const_cast< ::std::string*>(&_default_type_name_)),
+    extendee_(const_cast< ::std::string*>(&_default_extendee_)),
+    default_value_(const_cast< ::std::string*>(&_default_default_value_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+    options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance());
+  }
+}
+
+FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    number_(0),
+    label_(1),
+    type_(1),
+    type_name_(const_cast< ::std::string*>(&_default_type_name_)),
+    extendee_(const_cast< ::std::string*>(&_default_extendee_)),
+    default_value_(const_cast< ::std::string*>(&_default_default_value_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+FieldDescriptorProto::~FieldDescriptorProto() {
+  if (name_ != &_default_name_) {
+    delete name_;
+  }
+  if (type_name_ != &_default_type_name_) {
+    delete type_name_;
+  }
+  if (extendee_ != &_default_extendee_) {
+    delete extendee_;
+  }
+  if (default_value_ != &_default_default_value_) {
+    delete default_value_;
+  }
+  if (this != &default_instance_) {
+    delete options_;
+  }
+}
+
+const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() {
+  if (FieldDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return FieldDescriptorProto_descriptor_;
+}
+
+FieldDescriptorProto* FieldDescriptorProto::New() const {
+  return new FieldDescriptorProto;
+}
+
+void FieldDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (_has_bit(0)) {
+      if (name_ != &_default_name_) {
+        name_->clear();
+      }
+    }
+    number_ = 0;
+    label_ = 1;
+    type_ = 1;
+    if (_has_bit(4)) {
+      if (type_name_ != &_default_type_name_) {
+        type_name_->clear();
+      }
+    }
+    if (_has_bit(5)) {
+      if (extendee_ != &_default_extendee_) {
+        extendee_->clear();
+      }
+    }
+    if (_has_bit(6)) {
+      if (default_value_ != &_default_default_value_) {
+        default_value_->clear();
+      }
+    }
+    if (_has_bit(7)) {
+      if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
+    }
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool FieldDescriptorProto::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)) {
+      // optional string name = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name()));
+        if (input->ExpectTag(18)) goto parse_extendee;
+        break;
+      }
+      
+      // optional string extendee = 2;
+      case 2: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_extendee:
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_extendee()));
+        if (input->ExpectTag(24)) goto parse_number;
+        break;
+      }
+      
+      // optional int32 number = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+          goto handle_uninterpreted;
+        }
+       parse_number:
+        DO_(::google::protobuf::internal::WireFormat::ReadInt32(
+              input, &number_));
+        _set_bit(1);
+        if (input->ExpectTag(32)) goto parse_label;
+        break;
+      }
+      
+      // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+      case 4: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+          goto handle_uninterpreted;
+        }
+       parse_label:
+        int value;
+        DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));
+        if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) {
+          set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value));
+        } else {
+          mutable_unknown_fields()->AddField(4)->add_varint(value);
+        }
+        if (input->ExpectTag(40)) goto parse_type;
+        break;
+      }
+      
+      // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+      case 5: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+          goto handle_uninterpreted;
+        }
+       parse_type:
+        int value;
+        DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));
+        if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) {
+          set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value));
+        } else {
+          mutable_unknown_fields()->AddField(5)->add_varint(value);
+        }
+        if (input->ExpectTag(50)) goto parse_type_name;
+        break;
+      }
+      
+      // optional string type_name = 6;
+      case 6: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_type_name:
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_type_name()));
+        if (input->ExpectTag(58)) goto parse_default_value;
+        break;
+      }
+      
+      // optional string default_value = 7;
+      case 7: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_default_value:
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_default_value()));
+        if (input->ExpectTag(66)) goto parse_options;
+        break;
+      }
+      
+      // optional .google.protobuf.FieldOptions options = 8;
+      case 8: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_options:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, mutable_options()));
+        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 FieldDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional string name = 1;
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output));
+  }
+  
+  // optional string extendee = 2;
+  if (_has_bit(5)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(2, this->extendee(), output));
+  }
+  
+  // optional int32 number = 3;
+  if (_has_bit(1)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteInt32(3, this->number(), output));
+  }
+  
+  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+  if (_has_bit(2)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteEnum(4, this->label(), output));
+  }
+  
+  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+  if (_has_bit(3)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteEnum(5, this->type(), output));
+  }
+  
+  // optional string type_name = 6;
+  if (_has_bit(4)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(6, this->type_name(), output));
+  }
+  
+  // optional string default_value = 7;
+  if (_has_bit(6)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(7, this->default_value(), output));
+  }
+  
+  // optional .google.protobuf.FieldOptions options = 8;
+  if (_has_bit(7)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(8, this->options(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int FieldDescriptorProto::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional string name = 1;
+    if (has_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->name());
+    }
+    
+    // optional int32 number = 3;
+    if (has_number()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::Int32Size(
+          this->number());
+    }
+    
+    // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+    if (has_label()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::EnumSize(this->label());
+    }
+    
+    // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+    if (has_type()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::EnumSize(this->type());
+    }
+    
+    // optional string type_name = 6;
+    if (has_type_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->type_name());
+    }
+    
+    // optional string extendee = 2;
+    if (has_extendee()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->extendee());
+    }
+    
+    // optional string default_value = 7;
+    if (has_default_value()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->default_value());
+    }
+    
+    // optional .google.protobuf.FieldOptions options = 8;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+          this->options());
+    }
+    
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const FieldDescriptorProto* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const FieldDescriptorProto*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_name(from.name());
+    }
+    if (from._has_bit(1)) {
+      set_number(from.number());
+    }
+    if (from._has_bit(2)) {
+      set_label(from.label());
+    }
+    if (from._has_bit(3)) {
+      set_type(from.type());
+    }
+    if (from._has_bit(4)) {
+      set_type_name(from.type_name());
+    }
+    if (from._has_bit(5)) {
+      set_extendee(from.extendee());
+    }
+    if (from._has_bit(6)) {
+      set_default_value(from.default_value());
+    }
+    if (from._has_bit(7)) {
+      mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FieldDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool FieldDescriptorProto::IsInitialized() const {
+  
+  return true;
+}
+
+const ::google::protobuf::Descriptor* FieldDescriptorProto::GetDescriptor() const {
+  return descriptor();
+}
+
+const ::google::protobuf::Message::Reflection*
+FieldDescriptorProto::GetReflection() const {
+  return &_reflection_;
+}
+
+::google::protobuf::Message::Reflection* FieldDescriptorProto::GetReflection() {
+  return &_reflection_;
+}
+
+// ===================================================================
+
+const EnumDescriptorProto EnumDescriptorProto::default_instance_;
+
+const ::std::string EnumDescriptorProto::_default_name_;
+
+
+const int EnumDescriptorProto::_offsets_[3] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, value_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, options_),
+};
+
+EnumDescriptorProto::EnumDescriptorProto()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+    options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance());
+  }
+}
+
+EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+EnumDescriptorProto::~EnumDescriptorProto() {
+  if (name_ != &_default_name_) {
+    delete name_;
+  }
+  if (this != &default_instance_) {
+    delete options_;
+  }
+}
+
+const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() {
+  if (EnumDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return EnumDescriptorProto_descriptor_;
+}
+
+EnumDescriptorProto* EnumDescriptorProto::New() const {
+  return new EnumDescriptorProto;
+}
+
+void EnumDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (_has_bit(0)) {
+      if (name_ != &_default_name_) {
+        name_->clear();
+      }
+    }
+    if (_has_bit(2)) {
+      if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
+    }
+  }
+  value_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool EnumDescriptorProto::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)) {
+      // optional string name = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name()));
+        if (input->ExpectTag(18)) goto parse_value;
+        break;
+      }
+      
+      // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+      case 2: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_value:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_value()));
+        if (input->ExpectTag(18)) goto parse_value;
+        if (input->ExpectTag(26)) goto parse_options;
+        break;
+      }
+      
+      // optional .google.protobuf.EnumOptions options = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_options:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, mutable_options()));
+        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 EnumDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional string name = 1;
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output));
+  }
+  
+  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+  for (int i = 0; i < value_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->value(i), output));
+  }
+  
+  // optional .google.protobuf.EnumOptions options = 3;
+  if (_has_bit(2)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->options(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int EnumDescriptorProto::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional string name = 1;
+    if (has_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->name());
+    }
+    
+    // optional .google.protobuf.EnumOptions options = 3;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+          this->options());
+    }
+    
+  }
+  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+  total_size += 1 * value_size();
+  for (int i = 0; i < value_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->value(i));
+  }
+  
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const EnumDescriptorProto* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const EnumDescriptorProto*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  value_.MergeFrom(from.value_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_name(from.name());
+    }
+    if (from._has_bit(2)) {
+      mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void EnumDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EnumDescriptorProto::IsInitialized() const {
+  
+  return true;
+}
+
+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 EnumValueDescriptorProto EnumValueDescriptorProto::default_instance_;
+
+const ::std::string EnumValueDescriptorProto::_default_name_;
+
+
+const int EnumValueDescriptorProto::_offsets_[3] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, number_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, options_),
+};
+
+EnumValueDescriptorProto::EnumValueDescriptorProto()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    number_(0),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+    options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance());
+  }
+}
+
+EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    number_(0),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+EnumValueDescriptorProto::~EnumValueDescriptorProto() {
+  if (name_ != &_default_name_) {
+    delete name_;
+  }
+  if (this != &default_instance_) {
+    delete options_;
+  }
+}
+
+const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() {
+  if (EnumValueDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return EnumValueDescriptorProto_descriptor_;
+}
+
+EnumValueDescriptorProto* EnumValueDescriptorProto::New() const {
+  return new EnumValueDescriptorProto;
+}
+
+void EnumValueDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (_has_bit(0)) {
+      if (name_ != &_default_name_) {
+        name_->clear();
+      }
+    }
+    number_ = 0;
+    if (_has_bit(2)) {
+      if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
+    }
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool EnumValueDescriptorProto::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)) {
+      // optional string name = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name()));
+        if (input->ExpectTag(16)) goto parse_number;
+        break;
+      }
+      
+      // optional int32 number = 2;
+      case 2: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+          goto handle_uninterpreted;
+        }
+       parse_number:
+        DO_(::google::protobuf::internal::WireFormat::ReadInt32(
+              input, &number_));
+        _set_bit(1);
+        if (input->ExpectTag(26)) goto parse_options;
+        break;
+      }
+      
+      // optional .google.protobuf.EnumValueOptions options = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_options:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, mutable_options()));
+        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 EnumValueDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional string name = 1;
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output));
+  }
+  
+  // optional int32 number = 2;
+  if (_has_bit(1)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteInt32(2, this->number(), output));
+  }
+  
+  // optional .google.protobuf.EnumValueOptions options = 3;
+  if (_has_bit(2)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->options(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int EnumValueDescriptorProto::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional string name = 1;
+    if (has_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->name());
+    }
+    
+    // optional int32 number = 2;
+    if (has_number()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::Int32Size(
+          this->number());
+    }
+    
+    // optional .google.protobuf.EnumValueOptions options = 3;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+          this->options());
+    }
+    
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const EnumValueDescriptorProto* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const EnumValueDescriptorProto*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_name(from.name());
+    }
+    if (from._has_bit(1)) {
+      set_number(from.number());
+    }
+    if (from._has_bit(2)) {
+      mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void EnumValueDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EnumValueDescriptorProto::IsInitialized() const {
+  
+  return true;
+}
+
+const ::google::protobuf::Descriptor* EnumValueDescriptorProto::GetDescriptor() const {
+  return descriptor();
+}
+
+const ::google::protobuf::Message::Reflection*
+EnumValueDescriptorProto::GetReflection() const {
+  return &_reflection_;
+}
+
+::google::protobuf::Message::Reflection* EnumValueDescriptorProto::GetReflection() {
+  return &_reflection_;
+}
+
+// ===================================================================
+
+const ServiceDescriptorProto ServiceDescriptorProto::default_instance_;
+
+const ::std::string ServiceDescriptorProto::_default_name_;
+
+
+const int ServiceDescriptorProto::_offsets_[3] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, method_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, options_),
+};
+
+ServiceDescriptorProto::ServiceDescriptorProto()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+    options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance());
+  }
+}
+
+ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    name_(const_cast< ::std::string*>(&_default_name_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+ServiceDescriptorProto::~ServiceDescriptorProto() {
+  if (name_ != &_default_name_) {
+    delete name_;
+  }
+  if (this != &default_instance_) {
+    delete options_;
+  }
+}
+
+const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() {
+  if (ServiceDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return ServiceDescriptorProto_descriptor_;
+}
+
+ServiceDescriptorProto* ServiceDescriptorProto::New() const {
+  return new ServiceDescriptorProto;
+}
+
+void ServiceDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (_has_bit(0)) {
+      if (name_ != &_default_name_) {
+        name_->clear();
+      }
+    }
+    if (_has_bit(2)) {
+      if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
+    }
+  }
+  method_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool ServiceDescriptorProto::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)) {
+      // optional string name = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name()));
+        if (input->ExpectTag(18)) goto parse_method;
+        break;
+      }
+      
+      // repeated .google.protobuf.MethodDescriptorProto method = 2;
+      case 2: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_method:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, add_method()));
+        if (input->ExpectTag(18)) goto parse_method;
+        if (input->ExpectTag(26)) goto parse_options;
+        break;
+      }
+      
+      // optional .google.protobuf.ServiceOptions options = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_options:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, mutable_options()));
+        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 ServiceDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional string name = 1;
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output));
+  }
+  
+  // repeated .google.protobuf.MethodDescriptorProto method = 2;
+  for (int i = 0; i < method_.size(); i++) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->method(i), output));
+  }
+  
+  // optional .google.protobuf.ServiceOptions options = 3;
+  if (_has_bit(2)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->options(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int ServiceDescriptorProto::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional string name = 1;
+    if (has_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->name());
+    }
+    
+    // optional .google.protobuf.ServiceOptions options = 3;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+          this->options());
+    }
+    
+  }
+  // repeated .google.protobuf.MethodDescriptorProto method = 2;
+  total_size += 1 * method_size();
+  for (int i = 0; i < method_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+        this->method(i));
+  }
+  
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const ServiceDescriptorProto* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const ServiceDescriptorProto*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  method_.MergeFrom(from.method_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_name(from.name());
+    }
+    if (from._has_bit(2)) {
+      mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void ServiceDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ServiceDescriptorProto::IsInitialized() const {
+  
+  return true;
+}
+
+const ::google::protobuf::Descriptor* ServiceDescriptorProto::GetDescriptor() const {
+  return descriptor();
+}
+
+const ::google::protobuf::Message::Reflection*
+ServiceDescriptorProto::GetReflection() const {
+  return &_reflection_;
+}
+
+::google::protobuf::Message::Reflection* ServiceDescriptorProto::GetReflection() {
+  return &_reflection_;
+}
+
+// ===================================================================
+
+const MethodDescriptorProto MethodDescriptorProto::default_instance_;
+
+const ::std::string MethodDescriptorProto::_default_name_;
+const ::std::string MethodDescriptorProto::_default_input_type_;
+const ::std::string MethodDescriptorProto::_default_output_type_;
+
+const int MethodDescriptorProto::_offsets_[4] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, input_type_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, output_type_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, options_),
+};
+
+MethodDescriptorProto::MethodDescriptorProto()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _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_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+    options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance());
+  }
+}
+
+MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _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_)),
+    options_(NULL) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+MethodDescriptorProto::~MethodDescriptorProto() {
+  if (name_ != &_default_name_) {
+    delete name_;
+  }
+  if (input_type_ != &_default_input_type_) {
+    delete input_type_;
+  }
+  if (output_type_ != &_default_output_type_) {
+    delete output_type_;
+  }
+  if (this != &default_instance_) {
+    delete options_;
+  }
+}
+
+const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() {
+  if (MethodDescriptorProto_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return MethodDescriptorProto_descriptor_;
+}
+
+MethodDescriptorProto* MethodDescriptorProto::New() const {
+  return new MethodDescriptorProto;
+}
+
+void MethodDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (_has_bit(0)) {
+      if (name_ != &_default_name_) {
+        name_->clear();
+      }
+    }
+    if (_has_bit(1)) {
+      if (input_type_ != &_default_input_type_) {
+        input_type_->clear();
+      }
+    }
+    if (_has_bit(2)) {
+      if (output_type_ != &_default_output_type_) {
+        output_type_->clear();
+      }
+    }
+    if (_has_bit(3)) {
+      if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
+    }
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool MethodDescriptorProto::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)) {
+      // optional string name = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name()));
+        if (input->ExpectTag(18)) goto parse_input_type;
+        break;
+      }
+      
+      // optional string input_type = 2;
+      case 2: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_input_type:
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_input_type()));
+        if (input->ExpectTag(26)) goto parse_output_type;
+        break;
+      }
+      
+      // optional string output_type = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_output_type:
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_output_type()));
+        if (input->ExpectTag(34)) goto parse_options;
+        break;
+      }
+      
+      // optional .google.protobuf.MethodOptions options = 4;
+      case 4: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_options:
+        DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(
+             input, mutable_options()));
+        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 MethodDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional string name = 1;
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output));
+  }
+  
+  // optional string input_type = 2;
+  if (_has_bit(1)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(2, this->input_type(), output));
+  }
+  
+  // optional string output_type = 3;
+  if (_has_bit(2)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(3, this->output_type(), output));
+  }
+  
+  // optional .google.protobuf.MethodOptions options = 4;
+  if (_has_bit(3)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->options(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int MethodDescriptorProto::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional string name = 1;
+    if (has_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->name());
+    }
+    
+    // optional string input_type = 2;
+    if (has_input_type()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->input_type());
+    }
+    
+    // optional string output_type = 3;
+    if (has_output_type()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->output_type());
+    }
+    
+    // optional .google.protobuf.MethodOptions options = 4;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual(
+          this->options());
+    }
+    
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const MethodDescriptorProto* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const MethodDescriptorProto*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_name(from.name());
+    }
+    if (from._has_bit(1)) {
+      set_input_type(from.input_type());
+    }
+    if (from._has_bit(2)) {
+      set_output_type(from.output_type());
+    }
+    if (from._has_bit(3)) {
+      mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void MethodDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool MethodDescriptorProto::IsInitialized() const {
+  
+  return true;
+}
+
+const ::google::protobuf::Descriptor* MethodDescriptorProto::GetDescriptor() const {
+  return descriptor();
+}
+
+const ::google::protobuf::Message::Reflection*
+MethodDescriptorProto::GetReflection() const {
+  return &_reflection_;
+}
+
+::google::protobuf::Message::Reflection* MethodDescriptorProto::GetReflection() {
+  return &_reflection_;
+}
+
+// ===================================================================
+
+const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
+  if (FileOptions_OptimizeMode_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return FileOptions_OptimizeMode_descriptor_;
+}
+bool FileOptions_OptimizeMode_IsValid(int value) {
+  switch(value) {
+    case 1:
+    case 2:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#ifndef _MSC_VER
+const FileOptions_OptimizeMode FileOptions::SPEED;
+const FileOptions_OptimizeMode FileOptions::CODE_SIZE;
+const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
+const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
+#endif  // _MSC_VER
+const FileOptions FileOptions::default_instance_;
+
+const ::std::string FileOptions::_default_java_package_;
+const ::std::string FileOptions::_default_java_outer_classname_;
+
+
+const int FileOptions::_offsets_[4] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_),
+};
+
+FileOptions::FileOptions()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _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),
+    optimize_for_(2) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+  }
+}
+
+FileOptions::FileOptions(const FileOptions& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _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),
+    optimize_for_(2) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+FileOptions::~FileOptions() {
+  if (java_package_ != &_default_java_package_) {
+    delete java_package_;
+  }
+  if (java_outer_classname_ != &_default_java_outer_classname_) {
+    delete java_outer_classname_;
+  }
+  if (this != &default_instance_) {
+  }
+}
+
+const ::google::protobuf::Descriptor* FileOptions::descriptor() {
+  if (FileOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return FileOptions_descriptor_;
+}
+
+FileOptions* FileOptions::New() const {
+  return new FileOptions;
+}
+
+void FileOptions::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (_has_bit(0)) {
+      if (java_package_ != &_default_java_package_) {
+        java_package_->clear();
+      }
+    }
+    if (_has_bit(1)) {
+      if (java_outer_classname_ != &_default_java_outer_classname_) {
+        java_outer_classname_->clear();
+      }
+    }
+    java_multiple_files_ = false;
+    optimize_for_ = 2;
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool FileOptions::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)) {
+      // optional string java_package = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_java_package()));
+        if (input->ExpectTag(66)) goto parse_java_outer_classname;
+        break;
+      }
+      
+      // optional string java_outer_classname = 8;
+      case 8: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_java_outer_classname:
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_java_outer_classname()));
+        if (input->ExpectTag(72)) goto parse_optimize_for;
+        break;
+      }
+      
+      // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = CODE_SIZE];
+      case 9: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+          goto handle_uninterpreted;
+        }
+       parse_optimize_for:
+        int value;
+        DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));
+        if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) {
+          set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value));
+        } else {
+          mutable_unknown_fields()->AddField(9)->add_varint(value);
+        }
+        if (input->ExpectTag(80)) goto parse_java_multiple_files;
+        break;
+      }
+      
+      // optional bool java_multiple_files = 10 [default = false];
+      case 10: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+          goto handle_uninterpreted;
+        }
+       parse_java_multiple_files:
+        DO_(::google::protobuf::internal::WireFormat::ReadBool(
+              input, &java_multiple_files_));
+        _set_bit(2);
+        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 FileOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional string java_package = 1;
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->java_package(), output));
+  }
+  
+  // optional string java_outer_classname = 8;
+  if (_has_bit(1)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(8, this->java_outer_classname(), output));
+  }
+  
+  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = CODE_SIZE];
+  if (_has_bit(3)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteEnum(9, this->optimize_for(), output));
+  }
+  
+  // optional bool java_multiple_files = 10 [default = false];
+  if (_has_bit(2)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteBool(10, this->java_multiple_files(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int FileOptions::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional string java_package = 1;
+    if (has_java_package()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->java_package());
+    }
+    
+    // optional string java_outer_classname = 8;
+    if (has_java_outer_classname()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->java_outer_classname());
+    }
+    
+    // optional bool java_multiple_files = 10 [default = false];
+    if (has_java_multiple_files()) {
+      total_size += 1 + 1;
+    }
+    
+    // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = CODE_SIZE];
+    if (has_optimize_for()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::EnumSize(this->optimize_for());
+    }
+    
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void FileOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const FileOptions* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const FileOptions*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FileOptions::MergeFrom(const FileOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_java_package(from.java_package());
+    }
+    if (from._has_bit(1)) {
+      set_java_outer_classname(from.java_outer_classname());
+    }
+    if (from._has_bit(2)) {
+      set_java_multiple_files(from.java_multiple_files());
+    }
+    if (from._has_bit(3)) {
+      set_optimize_for(from.optimize_for());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FileOptions::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void FileOptions::CopyFrom(const FileOptions& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool FileOptions::IsInitialized() const {
+  
+  return true;
+}
+
+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 MessageOptions MessageOptions::default_instance_;
+
+
+const int MessageOptions::_offsets_[1] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_),
+};
+
+MessageOptions::MessageOptions()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    message_set_wire_format_(false) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+  }
+}
+
+MessageOptions::MessageOptions(const MessageOptions& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    message_set_wire_format_(false) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+MessageOptions::~MessageOptions() {
+  if (this != &default_instance_) {
+  }
+}
+
+const ::google::protobuf::Descriptor* MessageOptions::descriptor() {
+  if (MessageOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return MessageOptions_descriptor_;
+}
+
+MessageOptions* MessageOptions::New() const {
+  return new MessageOptions;
+}
+
+void MessageOptions::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    message_set_wire_format_ = false;
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool MessageOptions::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)) {
+      // optional bool message_set_wire_format = 1 [default = false];
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+          goto handle_uninterpreted;
+        }
+        DO_(::google::protobuf::internal::WireFormat::ReadBool(
+              input, &message_set_wire_format_));
+        _set_bit(0);
+        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 MessageOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional bool message_set_wire_format = 1 [default = false];
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteBool(1, this->message_set_wire_format(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int MessageOptions::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional bool message_set_wire_format = 1 [default = false];
+    if (has_message_set_wire_format()) {
+      total_size += 1 + 1;
+    }
+    
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const MessageOptions* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const MessageOptions*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void MessageOptions::MergeFrom(const MessageOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_message_set_wire_format(from.message_set_wire_format());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void MessageOptions::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void MessageOptions::CopyFrom(const MessageOptions& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool MessageOptions::IsInitialized() const {
+  
+  return true;
+}
+
+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::EnumDescriptor* FieldOptions_CType_descriptor() {
+  if (FieldOptions_CType_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return FieldOptions_CType_descriptor_;
+}
+bool FieldOptions_CType_IsValid(int value) {
+  switch(value) {
+    case 1:
+    case 2:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#ifndef _MSC_VER
+const FieldOptions_CType FieldOptions::CORD;
+const FieldOptions_CType FieldOptions::STRING_PIECE;
+const FieldOptions_CType FieldOptions::CType_MIN;
+const FieldOptions_CType FieldOptions::CType_MAX;
+#endif  // _MSC_VER
+const FieldOptions FieldOptions::default_instance_;
+
+
+const ::std::string FieldOptions::_default_experimental_map_key_;
+const int FieldOptions::_offsets_[2] = {
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_),
+  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, experimental_map_key_),
+};
+
+FieldOptions::FieldOptions()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    ctype_(1),
+    experimental_map_key_(const_cast< ::std::string*>(&_default_experimental_map_key_)) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  if (this == &default_instance_) {
+  }
+}
+
+FieldOptions::FieldOptions(const FieldOptions& from)
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _cached_size_(0),
+    ctype_(1),
+    experimental_map_key_(const_cast< ::std::string*>(&_default_experimental_map_key_)) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+FieldOptions::~FieldOptions() {
+  if (experimental_map_key_ != &_default_experimental_map_key_) {
+    delete experimental_map_key_;
+  }
+  if (this != &default_instance_) {
+  }
+}
+
+const ::google::protobuf::Descriptor* FieldOptions::descriptor() {
+  if (FieldOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return FieldOptions_descriptor_;
+}
+
+FieldOptions* FieldOptions::New() const {
+  return new FieldOptions;
+}
+
+void FieldOptions::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    ctype_ = 1;
+    if (_has_bit(1)) {
+      if (experimental_map_key_ != &_default_experimental_map_key_) {
+        experimental_map_key_->clear();
+      }
+    }
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool FieldOptions::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)) {
+      // optional .google.protobuf.FieldOptions.CType ctype = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) {
+          goto handle_uninterpreted;
+        }
+        int value;
+        DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));
+        if (::google::protobuf::FieldOptions_CType_IsValid(value)) {
+          set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value));
+        } else {
+          mutable_unknown_fields()->AddField(1)->add_varint(value);
+        }
+        if (input->ExpectTag(74)) goto parse_experimental_map_key;
+        break;
+      }
+      
+      // optional string experimental_map_key = 9;
+      case 9: {
+        if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=
+            ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) {
+          goto handle_uninterpreted;
+        }
+       parse_experimental_map_key:
+        DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_experimental_map_key()));
+        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 FieldOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  // optional .google.protobuf.FieldOptions.CType ctype = 1;
+  if (_has_bit(0)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteEnum(1, this->ctype(), output));
+  }
+  
+  // optional string experimental_map_key = 9;
+  if (_has_bit(1)) {
+    DO_(::google::protobuf::internal::WireFormat::WriteString(9, this->experimental_map_key(), output));
+  }
+  
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int FieldOptions::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional .google.protobuf.FieldOptions.CType ctype = 1;
+    if (has_ctype()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::EnumSize(this->ctype());
+    }
+    
+    // optional string experimental_map_key = 9;
+    if (has_experimental_map_key()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormat::StringSize(this->experimental_map_key());
+    }
+    
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const FieldOptions* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const FieldOptions*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(
+      descriptor(), *from.GetReflection(), &_reflection_);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FieldOptions::MergeFrom(const FieldOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_ctype(from.ctype());
+    }
+    if (from._has_bit(1)) {
+      set_experimental_map_key(from.experimental_map_key());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FieldOptions::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void FieldOptions::CopyFrom(const FieldOptions& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool FieldOptions::IsInitialized() const {
+  
+  return true;
+}
+
+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 EnumOptions EnumOptions::default_instance_;
+
+const int EnumOptions::_offsets_[1] = {
+};
+
+EnumOptions::EnumOptions()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _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) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+EnumOptions::~EnumOptions() {
+  if (this != &default_instance_) {
+  }
+}
+
+const ::google::protobuf::Descriptor* EnumOptions::descriptor() {
+  if (EnumOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return EnumOptions_descriptor_;
+}
+
+EnumOptions* EnumOptions::New() const {
+  return new EnumOptions;
+}
+
+void EnumOptions::Clear() {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool EnumOptions::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  ::google::protobuf::uint32 tag;
+  while ((tag = input->ReadTag()) != 0) {
+    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()));
+  }
+  return true;
+#undef DO_
+}
+
+bool EnumOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int EnumOptions::ByteSize() const {
+  int total_size = 0;
+  
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+}
+
+void EnumOptions::MergeFrom(const EnumOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void EnumOptions::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EnumOptions::CopyFrom(const EnumOptions& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EnumOptions::IsInitialized() const {
+  
+  return true;
+}
+
+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 EnumValueOptions EnumValueOptions::default_instance_;
+
+const int EnumValueOptions::_offsets_[1] = {
+};
+
+EnumValueOptions::EnumValueOptions()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _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) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+EnumValueOptions::~EnumValueOptions() {
+  if (this != &default_instance_) {
+  }
+}
+
+const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() {
+  if (EnumValueOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return EnumValueOptions_descriptor_;
+}
+
+EnumValueOptions* EnumValueOptions::New() const {
+  return new EnumValueOptions;
+}
+
+void EnumValueOptions::Clear() {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool EnumValueOptions::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  ::google::protobuf::uint32 tag;
+  while ((tag = input->ReadTag()) != 0) {
+    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()));
+  }
+  return true;
+#undef DO_
+}
+
+bool EnumValueOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int EnumValueOptions::ByteSize() const {
+  int total_size = 0;
+  
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+}
+
+void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void EnumValueOptions::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EnumValueOptions::CopyFrom(const EnumValueOptions& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EnumValueOptions::IsInitialized() const {
+  
+  return true;
+}
+
+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 ServiceOptions ServiceOptions::default_instance_;
+
+const int ServiceOptions::_offsets_[1] = {
+};
+
+ServiceOptions::ServiceOptions()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _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) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+ServiceOptions::~ServiceOptions() {
+  if (this != &default_instance_) {
+  }
+}
+
+const ::google::protobuf::Descriptor* ServiceOptions::descriptor() {
+  if (ServiceOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return ServiceOptions_descriptor_;
+}
+
+ServiceOptions* ServiceOptions::New() const {
+  return new ServiceOptions;
+}
+
+void ServiceOptions::Clear() {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool ServiceOptions::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  ::google::protobuf::uint32 tag;
+  while ((tag = input->ReadTag()) != 0) {
+    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()));
+  }
+  return true;
+#undef DO_
+}
+
+bool ServiceOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int ServiceOptions::ByteSize() const {
+  int total_size = 0;
+  
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+}
+
+void ServiceOptions::MergeFrom(const ServiceOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void ServiceOptions::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ServiceOptions::CopyFrom(const ServiceOptions& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ServiceOptions::IsInitialized() const {
+  
+  return true;
+}
+
+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 MethodOptions MethodOptions::default_instance_;
+
+const int MethodOptions::_offsets_[1] = {
+};
+
+MethodOptions::MethodOptions()
+  : _reflection_(descriptor(),
+                 this, &default_instance_,
+                 _offsets_, _has_bits_, NULL),
+    _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) {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  MergeFrom(from);
+}
+
+MethodOptions::~MethodOptions() {
+  if (this != &default_instance_) {
+  }
+}
+
+const ::google::protobuf::Descriptor* MethodOptions::descriptor() {
+  if (MethodOptions_descriptor_ == NULL) proto_BuildDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
+  return MethodOptions_descriptor_;
+}
+
+MethodOptions* MethodOptions::New() const {
+  return new MethodOptions;
+}
+
+void MethodOptions::Clear() {
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool MethodOptions::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  ::google::protobuf::uint32 tag;
+  while ((tag = input->ReadTag()) != 0) {
+    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()));
+  }
+  return true;
+#undef DO_
+}
+
+bool MethodOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  if (!unknown_fields().empty()) {
+    DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output));
+  }
+  return true;
+#undef DO_
+}
+
+int MethodOptions::ByteSize() const {
+  int total_size = 0;
+  
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  _cached_size_ = total_size;
+  return total_size;
+}
+
+void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+}
+
+void MethodOptions::MergeFrom(const MethodOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void MethodOptions::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void MethodOptions::CopyFrom(const MethodOptions& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool MethodOptions::IsInitialized() const {
+  
+  return true;
+}
+
+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_;
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
new file mode 100644
index 0000000..892f92d
--- /dev/null
+++ b/src/google/protobuf/descriptor.pb.h
@@ -0,0 +1,2958 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+
+#ifndef PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
+#define PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 2000000
+#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.
+#endif
+#if 2000001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers.  Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+
+namespace google {
+namespace protobuf {
+
+class FileDescriptorProto;
+class DescriptorProto;
+class DescriptorProto_ExtensionRange;
+class FieldDescriptorProto;
+class EnumDescriptorProto;
+class EnumValueDescriptorProto;
+class ServiceDescriptorProto;
+class MethodDescriptorProto;
+class FileOptions;
+class MessageOptions;
+class FieldOptions;
+class EnumOptions;
+class EnumValueOptions;
+class ServiceOptions;
+class MethodOptions;
+
+enum FieldDescriptorProto_Type {
+  FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
+  FieldDescriptorProto_Type_TYPE_FLOAT = 2,
+  FieldDescriptorProto_Type_TYPE_INT64 = 3,
+  FieldDescriptorProto_Type_TYPE_UINT64 = 4,
+  FieldDescriptorProto_Type_TYPE_INT32 = 5,
+  FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
+  FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
+  FieldDescriptorProto_Type_TYPE_BOOL = 8,
+  FieldDescriptorProto_Type_TYPE_STRING = 9,
+  FieldDescriptorProto_Type_TYPE_GROUP = 10,
+  FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
+  FieldDescriptorProto_Type_TYPE_BYTES = 12,
+  FieldDescriptorProto_Type_TYPE_UINT32 = 13,
+  FieldDescriptorProto_Type_TYPE_ENUM = 14,
+  FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
+  FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
+  FieldDescriptorProto_Type_TYPE_SINT32 = 17,
+  FieldDescriptorProto_Type_TYPE_SINT64 = 18,
+};
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor();
+LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value);
+const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
+const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
+
+enum FieldDescriptorProto_Label {
+  FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
+  FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
+  FieldDescriptorProto_Label_LABEL_REPEATED = 3,
+};
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor();
+LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value);
+const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
+
+enum FileOptions_OptimizeMode {
+  FileOptions_OptimizeMode_SPEED = 1,
+  FileOptions_OptimizeMode_CODE_SIZE = 2,
+};
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor();
+LIBPROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value);
+const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED;
+const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_CODE_SIZE;
+
+enum FieldOptions_CType {
+  FieldOptions_CType_CORD = 1,
+  FieldOptions_CType_STRING_PIECE = 2,
+};
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor();
+LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value);
+const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_CORD;
+const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE;
+
+// ===================================================================
+
+class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message {
+ public:
+  FileDescriptorProto();
+  virtual ~FileDescriptorProto();
+  
+  FileDescriptorProto(const FileDescriptorProto& from);
+  
+  inline FileDescriptorProto& operator=(const FileDescriptorProto& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const FileDescriptorProto& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  FileDescriptorProto* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const FileDescriptorProto& from);
+  void MergeFrom(const FileDescriptorProto& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline ::std::string* mutable_name();
+  
+  // optional string package = 2;
+  inline bool has_package() const;
+  inline void clear_package();
+  inline const ::std::string& package() const;
+  inline void set_package(const ::std::string& value);
+  inline void set_package(const char* value);
+  inline ::std::string* mutable_package();
+  
+  // repeated string dependency = 3;
+  inline int dependency_size() const;
+  inline void clear_dependency();
+  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
+  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency();
+  inline const ::std::string& dependency(int index) const;
+  inline ::std::string* mutable_dependency(int index);
+  inline void set_dependency(int index, const ::std::string& value);
+  inline void set_dependency(int index, const char* value);
+  inline ::std::string* add_dependency();
+  inline void add_dependency(const ::std::string& value);
+  inline void add_dependency(const char* value);
+  
+  // repeated .google.protobuf.DescriptorProto message_type = 4;
+  inline int message_type_size() const;
+  inline void clear_message_type();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& message_type() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* mutable_message_type();
+  inline const ::google::protobuf::DescriptorProto& message_type(int index) const;
+  inline ::google::protobuf::DescriptorProto* mutable_message_type(int index);
+  inline ::google::protobuf::DescriptorProto* add_message_type();
+  
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+  inline int enum_type_size() const;
+  inline void clear_enum_type();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& enum_type() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* mutable_enum_type();
+  inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
+  inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
+  inline ::google::protobuf::EnumDescriptorProto* add_enum_type();
+  
+  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+  inline int service_size() const;
+  inline void clear_service();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& service() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* mutable_service();
+  inline const ::google::protobuf::ServiceDescriptorProto& service(int index) const;
+  inline ::google::protobuf::ServiceDescriptorProto* mutable_service(int index);
+  inline ::google::protobuf::ServiceDescriptorProto* add_service();
+  
+  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+  inline int extension_size() const;
+  inline void clear_extension();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& extension() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* mutable_extension();
+  inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
+  inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
+  inline ::google::protobuf::FieldDescriptorProto* add_extension();
+  
+  // optional .google.protobuf.FileOptions options = 8;
+  inline bool has_options() const;
+  inline void clear_options();
+  inline const ::google::protobuf::FileOptions& options() const;
+  inline ::google::protobuf::FileOptions* mutable_options();
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  ::std::string* name_;
+  static const ::std::string _default_name_;
+  ::std::string* package_;
+  static const ::std::string _default_package_;
+  ::google::protobuf::RepeatedPtrField< ::std::string> dependency_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
+  ::google::protobuf::FileOptions* options_;
+  
+  static const FileDescriptorProto default_instance_;
+  static const int _offsets_[8];
+  
+  ::google::protobuf::uint32 _has_bits_[(8 + 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 DescriptorProto_ExtensionRange : public ::google::protobuf::Message {
+ public:
+  DescriptorProto_ExtensionRange();
+  virtual ~DescriptorProto_ExtensionRange();
+  
+  DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from);
+  
+  inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const DescriptorProto_ExtensionRange& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  DescriptorProto_ExtensionRange* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const DescriptorProto_ExtensionRange& from);
+  void MergeFrom(const DescriptorProto_ExtensionRange& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+  // optional int32 start = 1;
+  inline bool has_start() const;
+  inline void clear_start();
+  inline ::google::protobuf::int32 start() const;
+  inline void set_start(::google::protobuf::int32 value);
+  
+  // optional int32 end = 2;
+  inline bool has_end() const;
+  inline void clear_end();
+  inline ::google::protobuf::int32 end() const;
+  inline void set_end(::google::protobuf::int32 value);
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  ::google::protobuf::int32 start_;
+  ::google::protobuf::int32 end_;
+  
+  static const DescriptorProto_ExtensionRange default_instance_;
+  static const int _offsets_[2];
+  
+  ::google::protobuf::uint32 _has_bits_[(2 + 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 DescriptorProto : public ::google::protobuf::Message {
+ public:
+  DescriptorProto();
+  virtual ~DescriptorProto();
+  
+  DescriptorProto(const DescriptorProto& from);
+  
+  inline DescriptorProto& operator=(const DescriptorProto& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const DescriptorProto& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  DescriptorProto* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const DescriptorProto& from);
+  void MergeFrom(const DescriptorProto& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  typedef DescriptorProto_ExtensionRange ExtensionRange;
+  
+  // accessors -------------------------------------------------------
+  
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline ::std::string* mutable_name();
+  
+  // repeated .google.protobuf.FieldDescriptorProto field = 2;
+  inline int field_size() const;
+  inline void clear_field();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& field() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* mutable_field();
+  inline const ::google::protobuf::FieldDescriptorProto& field(int index) const;
+  inline ::google::protobuf::FieldDescriptorProto* mutable_field(int index);
+  inline ::google::protobuf::FieldDescriptorProto* add_field();
+  
+  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+  inline int extension_size() const;
+  inline void clear_extension();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& extension() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* mutable_extension();
+  inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
+  inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
+  inline ::google::protobuf::FieldDescriptorProto* add_extension();
+  
+  // repeated .google.protobuf.DescriptorProto nested_type = 3;
+  inline int nested_type_size() const;
+  inline void clear_nested_type();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& nested_type() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* mutable_nested_type();
+  inline const ::google::protobuf::DescriptorProto& nested_type(int index) const;
+  inline ::google::protobuf::DescriptorProto* mutable_nested_type(int index);
+  inline ::google::protobuf::DescriptorProto* add_nested_type();
+  
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+  inline int enum_type_size() const;
+  inline void clear_enum_type();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& enum_type() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* mutable_enum_type();
+  inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
+  inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
+  inline ::google::protobuf::EnumDescriptorProto* add_enum_type();
+  
+  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+  inline int extension_range_size() const;
+  inline void clear_extension_range();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& extension_range() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* mutable_extension_range();
+  inline const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const;
+  inline ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index);
+  inline ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range();
+  
+  // optional .google.protobuf.MessageOptions options = 7;
+  inline bool has_options() const;
+  inline void clear_options();
+  inline const ::google::protobuf::MessageOptions& options() const;
+  inline ::google::protobuf::MessageOptions* mutable_options();
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  ::std::string* name_;
+  static const ::std::string _default_name_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_;
+  ::google::protobuf::MessageOptions* options_;
+  
+  static const DescriptorProto default_instance_;
+  static const int _offsets_[7];
+  
+  ::google::protobuf::uint32 _has_bits_[(7 + 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 FieldDescriptorProto : public ::google::protobuf::Message {
+ public:
+  FieldDescriptorProto();
+  virtual ~FieldDescriptorProto();
+  
+  FieldDescriptorProto(const FieldDescriptorProto& from);
+  
+  inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const FieldDescriptorProto& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  FieldDescriptorProto* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const FieldDescriptorProto& from);
+  void MergeFrom(const FieldDescriptorProto& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  typedef FieldDescriptorProto_Type Type;
+  static const Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
+  static const Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
+  static const Type TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
+  static const Type TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
+  static const Type TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
+  static const Type TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
+  static const Type TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
+  static const Type TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
+  static const Type TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
+  static const Type TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
+  static const Type TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
+  static const Type TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
+  static const Type TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
+  static const Type TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
+  static const Type TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
+  static const Type TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
+  static const Type TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
+  static const Type TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Type_descriptor() {
+    return FieldDescriptorProto_Type_descriptor();
+  }
+  static inline bool Type_IsValid(int value) {
+    return FieldDescriptorProto_Type_IsValid(value);
+  }
+  static const Type Type_MIN =
+    FieldDescriptorProto_Type_Type_MIN;
+  static const Type Type_MAX =
+    FieldDescriptorProto_Type_Type_MAX;
+  
+  typedef FieldDescriptorProto_Label Label;
+  static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+  static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
+  static const Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Label_descriptor() {
+    return FieldDescriptorProto_Label_descriptor();
+  }
+  static inline bool Label_IsValid(int value) {
+    return FieldDescriptorProto_Label_IsValid(value);
+  }
+  static const Label Label_MIN =
+    FieldDescriptorProto_Label_Label_MIN;
+  static const Label Label_MAX =
+    FieldDescriptorProto_Label_Label_MAX;
+  
+  // accessors -------------------------------------------------------
+  
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline ::std::string* mutable_name();
+  
+  // optional int32 number = 3;
+  inline bool has_number() const;
+  inline void clear_number();
+  inline ::google::protobuf::int32 number() const;
+  inline void set_number(::google::protobuf::int32 value);
+  
+  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+  inline bool has_label() const;
+  inline void clear_label();
+  inline ::google::protobuf::FieldDescriptorProto_Label label() const;
+  inline void set_label(::google::protobuf::FieldDescriptorProto_Label value);
+  
+  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+  inline bool has_type() const;
+  inline void clear_type();
+  inline ::google::protobuf::FieldDescriptorProto_Type type() const;
+  inline void set_type(::google::protobuf::FieldDescriptorProto_Type value);
+  
+  // optional string type_name = 6;
+  inline bool has_type_name() const;
+  inline void clear_type_name();
+  inline const ::std::string& type_name() const;
+  inline void set_type_name(const ::std::string& value);
+  inline void set_type_name(const char* value);
+  inline ::std::string* mutable_type_name();
+  
+  // optional string extendee = 2;
+  inline bool has_extendee() const;
+  inline void clear_extendee();
+  inline const ::std::string& extendee() const;
+  inline void set_extendee(const ::std::string& value);
+  inline void set_extendee(const char* value);
+  inline ::std::string* mutable_extendee();
+  
+  // optional string default_value = 7;
+  inline bool has_default_value() const;
+  inline void clear_default_value();
+  inline const ::std::string& default_value() const;
+  inline void set_default_value(const ::std::string& value);
+  inline void set_default_value(const char* value);
+  inline ::std::string* mutable_default_value();
+  
+  // optional .google.protobuf.FieldOptions options = 8;
+  inline bool has_options() const;
+  inline void clear_options();
+  inline const ::google::protobuf::FieldOptions& options() const;
+  inline ::google::protobuf::FieldOptions* mutable_options();
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  ::std::string* name_;
+  static const ::std::string _default_name_;
+  ::google::protobuf::int32 number_;
+  int label_;
+  int type_;
+  ::std::string* type_name_;
+  static const ::std::string _default_type_name_;
+  ::std::string* extendee_;
+  static const ::std::string _default_extendee_;
+  ::std::string* default_value_;
+  static const ::std::string _default_default_value_;
+  ::google::protobuf::FieldOptions* options_;
+  
+  static const FieldDescriptorProto default_instance_;
+  static const int _offsets_[8];
+  
+  ::google::protobuf::uint32 _has_bits_[(8 + 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 EnumDescriptorProto : public ::google::protobuf::Message {
+ public:
+  EnumDescriptorProto();
+  virtual ~EnumDescriptorProto();
+  
+  EnumDescriptorProto(const EnumDescriptorProto& from);
+  
+  inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const EnumDescriptorProto& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  EnumDescriptorProto* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const EnumDescriptorProto& from);
+  void MergeFrom(const EnumDescriptorProto& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline ::std::string* mutable_name();
+  
+  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+  inline int value_size() const;
+  inline void clear_value();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& value() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* mutable_value();
+  inline const ::google::protobuf::EnumValueDescriptorProto& value(int index) const;
+  inline ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index);
+  inline ::google::protobuf::EnumValueDescriptorProto* add_value();
+  
+  // optional .google.protobuf.EnumOptions options = 3;
+  inline bool has_options() const;
+  inline void clear_options();
+  inline const ::google::protobuf::EnumOptions& options() const;
+  inline ::google::protobuf::EnumOptions* mutable_options();
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  ::std::string* name_;
+  static const ::std::string _default_name_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
+  ::google::protobuf::EnumOptions* options_;
+  
+  static const EnumDescriptorProto default_instance_;
+  static const int _offsets_[3];
+  
+  ::google::protobuf::uint32 _has_bits_[(3 + 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 EnumValueDescriptorProto : public ::google::protobuf::Message {
+ public:
+  EnumValueDescriptorProto();
+  virtual ~EnumValueDescriptorProto();
+  
+  EnumValueDescriptorProto(const EnumValueDescriptorProto& from);
+  
+  inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const EnumValueDescriptorProto& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  EnumValueDescriptorProto* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const EnumValueDescriptorProto& from);
+  void MergeFrom(const EnumValueDescriptorProto& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline ::std::string* mutable_name();
+  
+  // optional int32 number = 2;
+  inline bool has_number() const;
+  inline void clear_number();
+  inline ::google::protobuf::int32 number() const;
+  inline void set_number(::google::protobuf::int32 value);
+  
+  // optional .google.protobuf.EnumValueOptions options = 3;
+  inline bool has_options() const;
+  inline void clear_options();
+  inline const ::google::protobuf::EnumValueOptions& options() const;
+  inline ::google::protobuf::EnumValueOptions* mutable_options();
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  ::std::string* name_;
+  static const ::std::string _default_name_;
+  ::google::protobuf::int32 number_;
+  ::google::protobuf::EnumValueOptions* options_;
+  
+  static const EnumValueDescriptorProto default_instance_;
+  static const int _offsets_[3];
+  
+  ::google::protobuf::uint32 _has_bits_[(3 + 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 ServiceDescriptorProto : public ::google::protobuf::Message {
+ public:
+  ServiceDescriptorProto();
+  virtual ~ServiceDescriptorProto();
+  
+  ServiceDescriptorProto(const ServiceDescriptorProto& from);
+  
+  inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const ServiceDescriptorProto& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  ServiceDescriptorProto* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ServiceDescriptorProto& from);
+  void MergeFrom(const ServiceDescriptorProto& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline ::std::string* mutable_name();
+  
+  // repeated .google.protobuf.MethodDescriptorProto method = 2;
+  inline int method_size() const;
+  inline void clear_method();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& method() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* mutable_method();
+  inline const ::google::protobuf::MethodDescriptorProto& method(int index) const;
+  inline ::google::protobuf::MethodDescriptorProto* mutable_method(int index);
+  inline ::google::protobuf::MethodDescriptorProto* add_method();
+  
+  // optional .google.protobuf.ServiceOptions options = 3;
+  inline bool has_options() const;
+  inline void clear_options();
+  inline const ::google::protobuf::ServiceOptions& options() const;
+  inline ::google::protobuf::ServiceOptions* mutable_options();
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  ::std::string* name_;
+  static const ::std::string _default_name_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
+  ::google::protobuf::ServiceOptions* options_;
+  
+  static const ServiceDescriptorProto default_instance_;
+  static const int _offsets_[3];
+  
+  ::google::protobuf::uint32 _has_bits_[(3 + 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 MethodDescriptorProto : public ::google::protobuf::Message {
+ public:
+  MethodDescriptorProto();
+  virtual ~MethodDescriptorProto();
+  
+  MethodDescriptorProto(const MethodDescriptorProto& from);
+  
+  inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const MethodDescriptorProto& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  MethodDescriptorProto* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const MethodDescriptorProto& from);
+  void MergeFrom(const MethodDescriptorProto& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline ::std::string* mutable_name();
+  
+  // optional string input_type = 2;
+  inline bool has_input_type() const;
+  inline void clear_input_type();
+  inline const ::std::string& input_type() const;
+  inline void set_input_type(const ::std::string& value);
+  inline void set_input_type(const char* value);
+  inline ::std::string* mutable_input_type();
+  
+  // optional string output_type = 3;
+  inline bool has_output_type() const;
+  inline void clear_output_type();
+  inline const ::std::string& output_type() const;
+  inline void set_output_type(const ::std::string& value);
+  inline void set_output_type(const char* value);
+  inline ::std::string* mutable_output_type();
+  
+  // optional .google.protobuf.MethodOptions options = 4;
+  inline bool has_options() const;
+  inline void clear_options();
+  inline const ::google::protobuf::MethodOptions& options() const;
+  inline ::google::protobuf::MethodOptions* mutable_options();
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  ::std::string* name_;
+  static const ::std::string _default_name_;
+  ::std::string* input_type_;
+  static const ::std::string _default_input_type_;
+  ::std::string* output_type_;
+  static const ::std::string _default_output_type_;
+  ::google::protobuf::MethodOptions* options_;
+  
+  static const MethodDescriptorProto default_instance_;
+  static const int _offsets_[4];
+  
+  ::google::protobuf::uint32 _has_bits_[(4 + 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 FileOptions : public ::google::protobuf::Message {
+ public:
+  FileOptions();
+  virtual ~FileOptions();
+  
+  FileOptions(const FileOptions& from);
+  
+  inline FileOptions& operator=(const FileOptions& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const FileOptions& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  FileOptions* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const FileOptions& from);
+  void MergeFrom(const FileOptions& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  typedef FileOptions_OptimizeMode OptimizeMode;
+  static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED;
+  static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  OptimizeMode_descriptor() {
+    return FileOptions_OptimizeMode_descriptor();
+  }
+  static inline bool OptimizeMode_IsValid(int value) {
+    return FileOptions_OptimizeMode_IsValid(value);
+  }
+  static const OptimizeMode OptimizeMode_MIN =
+    FileOptions_OptimizeMode_OptimizeMode_MIN;
+  static const OptimizeMode OptimizeMode_MAX =
+    FileOptions_OptimizeMode_OptimizeMode_MAX;
+  
+  // accessors -------------------------------------------------------
+  
+  // optional string java_package = 1;
+  inline bool has_java_package() const;
+  inline void clear_java_package();
+  inline const ::std::string& java_package() const;
+  inline void set_java_package(const ::std::string& value);
+  inline void set_java_package(const char* value);
+  inline ::std::string* mutable_java_package();
+  
+  // optional string java_outer_classname = 8;
+  inline bool has_java_outer_classname() const;
+  inline void clear_java_outer_classname();
+  inline const ::std::string& java_outer_classname() const;
+  inline void set_java_outer_classname(const ::std::string& value);
+  inline void set_java_outer_classname(const char* value);
+  inline ::std::string* mutable_java_outer_classname();
+  
+  // optional bool java_multiple_files = 10 [default = false];
+  inline bool has_java_multiple_files() const;
+  inline void clear_java_multiple_files();
+  inline bool java_multiple_files() const;
+  inline void set_java_multiple_files(bool value);
+  
+  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = CODE_SIZE];
+  inline bool has_optimize_for() const;
+  inline void clear_optimize_for();
+  inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const;
+  inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  ::std::string* java_package_;
+  static const ::std::string _default_java_package_;
+  ::std::string* java_outer_classname_;
+  static const ::std::string _default_java_outer_classname_;
+  bool java_multiple_files_;
+  int optimize_for_;
+  
+  static const FileOptions default_instance_;
+  static const int _offsets_[4];
+  
+  ::google::protobuf::uint32 _has_bits_[(4 + 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 MessageOptions : public ::google::protobuf::Message {
+ public:
+  MessageOptions();
+  virtual ~MessageOptions();
+  
+  MessageOptions(const MessageOptions& from);
+  
+  inline MessageOptions& operator=(const MessageOptions& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const MessageOptions& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  MessageOptions* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const MessageOptions& from);
+  void MergeFrom(const MessageOptions& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+  // optional bool message_set_wire_format = 1 [default = false];
+  inline bool has_message_set_wire_format() const;
+  inline void clear_message_set_wire_format();
+  inline bool message_set_wire_format() const;
+  inline void set_message_set_wire_format(bool value);
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  bool message_set_wire_format_;
+  
+  static const MessageOptions 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 FieldOptions : public ::google::protobuf::Message {
+ public:
+  FieldOptions();
+  virtual ~FieldOptions();
+  
+  FieldOptions(const FieldOptions& from);
+  
+  inline FieldOptions& operator=(const FieldOptions& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const FieldOptions& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  FieldOptions* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const FieldOptions& from);
+  void MergeFrom(const FieldOptions& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  typedef FieldOptions_CType CType;
+  static const CType CORD = FieldOptions_CType_CORD;
+  static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  CType_descriptor() {
+    return FieldOptions_CType_descriptor();
+  }
+  static inline bool CType_IsValid(int value) {
+    return FieldOptions_CType_IsValid(value);
+  }
+  static const CType CType_MIN =
+    FieldOptions_CType_CType_MIN;
+  static const CType CType_MAX =
+    FieldOptions_CType_CType_MAX;
+  
+  // accessors -------------------------------------------------------
+  
+  // optional .google.protobuf.FieldOptions.CType ctype = 1;
+  inline bool has_ctype() const;
+  inline void clear_ctype();
+  inline ::google::protobuf::FieldOptions_CType ctype() const;
+  inline void set_ctype(::google::protobuf::FieldOptions_CType value);
+  
+  // optional string experimental_map_key = 9;
+  inline bool has_experimental_map_key() const;
+  inline void clear_experimental_map_key();
+  inline const ::std::string& experimental_map_key() const;
+  inline void set_experimental_map_key(const ::std::string& value);
+  inline void set_experimental_map_key(const char* value);
+  inline ::std::string* mutable_experimental_map_key();
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  int ctype_;
+  ::std::string* experimental_map_key_;
+  static const ::std::string _default_experimental_map_key_;
+  
+  static const FieldOptions default_instance_;
+  static const int _offsets_[2];
+  
+  ::google::protobuf::uint32 _has_bits_[(2 + 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 EnumOptions : public ::google::protobuf::Message {
+ public:
+  EnumOptions();
+  virtual ~EnumOptions();
+  
+  EnumOptions(const EnumOptions& from);
+  
+  inline EnumOptions& operator=(const EnumOptions& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const EnumOptions& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  EnumOptions* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const EnumOptions& from);
+  void MergeFrom(const EnumOptions& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  
+  static const EnumOptions default_instance_;
+  static const int _offsets_[1];
+  
+  ::google::protobuf::uint32 _has_bits_[1];
+  
+  // 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 EnumValueOptions : public ::google::protobuf::Message {
+ public:
+  EnumValueOptions();
+  virtual ~EnumValueOptions();
+  
+  EnumValueOptions(const EnumValueOptions& from);
+  
+  inline EnumValueOptions& operator=(const EnumValueOptions& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const EnumValueOptions& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  EnumValueOptions* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const EnumValueOptions& from);
+  void MergeFrom(const EnumValueOptions& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  
+  static const EnumValueOptions default_instance_;
+  static const int _offsets_[1];
+  
+  ::google::protobuf::uint32 _has_bits_[1];
+  
+  // 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 ServiceOptions : public ::google::protobuf::Message {
+ public:
+  ServiceOptions();
+  virtual ~ServiceOptions();
+  
+  ServiceOptions(const ServiceOptions& from);
+  
+  inline ServiceOptions& operator=(const ServiceOptions& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const ServiceOptions& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  ServiceOptions* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ServiceOptions& from);
+  void MergeFrom(const ServiceOptions& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  
+  static const ServiceOptions default_instance_;
+  static const int _offsets_[1];
+  
+  ::google::protobuf::uint32 _has_bits_[1];
+  
+  // 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 MethodOptions : public ::google::protobuf::Message {
+ public:
+  MethodOptions();
+  virtual ~MethodOptions();
+  
+  MethodOptions(const MethodOptions& from);
+  
+  inline MethodOptions& operator=(const MethodOptions& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline static const MethodOptions& default_instance() {
+    return default_instance_;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _reflection_.unknown_fields();
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _reflection_.mutable_unknown_fields();
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  
+  // implements Message ----------------------------------------------
+  
+  MethodOptions* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const MethodOptions& from);
+  void MergeFrom(const MethodOptions& 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::Message::Reflection* GetReflection() const;
+  ::google::protobuf::Message::Reflection* GetReflection();
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+ private:
+  ::google::protobuf::internal::GeneratedMessageReflection _reflection_;
+  mutable int _cached_size_;
+  
+  
+  static const MethodOptions default_instance_;
+  static const int _offsets_[1];
+  
+  ::google::protobuf::uint32 _has_bits_[1];
+  
+  // 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));
+  }
+};
+// ===================================================================
+
+
+// ===================================================================
+
+
+// ===================================================================
+
+// FileDescriptorProto
+
+// optional string name = 1;
+inline bool FileDescriptorProto::has_name() const {
+  return _has_bit(0);
+}
+inline void FileDescriptorProto::clear_name() {
+  if (name_ != &_default_name_) {
+    name_->clear();
+  }
+  _clear_bit(0);
+}
+inline const ::std::string& FileDescriptorProto::name() const {
+  return *name_;
+}
+inline void FileDescriptorProto::set_name(const ::std::string& value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline void FileDescriptorProto::set_name(const char* value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline ::std::string* FileDescriptorProto::mutable_name() {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  return name_;
+}
+
+// optional string package = 2;
+inline bool FileDescriptorProto::has_package() const {
+  return _has_bit(1);
+}
+inline void FileDescriptorProto::clear_package() {
+  if (package_ != &_default_package_) {
+    package_->clear();
+  }
+  _clear_bit(1);
+}
+inline const ::std::string& FileDescriptorProto::package() const {
+  return *package_;
+}
+inline void FileDescriptorProto::set_package(const ::std::string& value) {
+  _set_bit(1);
+  if (package_ == &_default_package_) {
+    package_ = new ::std::string;
+  }
+  package_->assign(value);
+}
+inline void FileDescriptorProto::set_package(const char* value) {
+  _set_bit(1);
+  if (package_ == &_default_package_) {
+    package_ = new ::std::string;
+  }
+  package_->assign(value);
+}
+inline ::std::string* FileDescriptorProto::mutable_package() {
+  _set_bit(1);
+  if (package_ == &_default_package_) {
+    package_ = new ::std::string;
+  }
+  return package_;
+}
+
+// repeated string dependency = 3;
+inline int FileDescriptorProto::dependency_size() const {
+  return dependency_.size();
+}
+inline void FileDescriptorProto::clear_dependency() {
+  dependency_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+FileDescriptorProto::dependency() const {
+  return dependency_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+FileDescriptorProto::mutable_dependency() {
+  return &dependency_;
+}
+inline const ::std::string& FileDescriptorProto::dependency(int index) const {
+  return dependency_.Get(index);
+}
+inline ::std::string* FileDescriptorProto::mutable_dependency(int index) {
+  return dependency_.Mutable(index);
+}
+inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
+  dependency_.Mutable(index)->assign(value);
+}
+inline void FileDescriptorProto::set_dependency(int index, const char* value) {
+  dependency_.Mutable(index)->assign(value);
+}
+inline ::std::string* FileDescriptorProto::add_dependency() {
+  return dependency_.Add();
+}
+inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
+  dependency_.Add()->assign(value);
+}
+inline void FileDescriptorProto::add_dependency(const char* value) {
+  dependency_.Add()->assign(value);
+}
+
+// repeated .google.protobuf.DescriptorProto message_type = 4;
+inline int FileDescriptorProto::message_type_size() const {
+  return message_type_.size();
+}
+inline void FileDescriptorProto::clear_message_type() {
+  message_type_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+FileDescriptorProto::message_type() const {
+  return message_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+FileDescriptorProto::mutable_message_type() {
+  return &message_type_;
+}
+inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const {
+  return message_type_.Get(index);
+}
+inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
+  return message_type_.Mutable(index);
+}
+inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() {
+  return message_type_.Add();
+}
+
+// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+inline int FileDescriptorProto::enum_type_size() const {
+  return enum_type_.size();
+}
+inline void FileDescriptorProto::clear_enum_type() {
+  enum_type_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+FileDescriptorProto::enum_type() const {
+  return enum_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+FileDescriptorProto::mutable_enum_type() {
+  return &enum_type_;
+}
+inline const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const {
+  return enum_type_.Get(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
+  return enum_type_.Mutable(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
+  return enum_type_.Add();
+}
+
+// repeated .google.protobuf.ServiceDescriptorProto service = 6;
+inline int FileDescriptorProto::service_size() const {
+  return service_.size();
+}
+inline void FileDescriptorProto::clear_service() {
+  service_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
+FileDescriptorProto::service() const {
+  return service_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
+FileDescriptorProto::mutable_service() {
+  return &service_;
+}
+inline const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const {
+  return service_.Get(index);
+}
+inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
+  return service_.Mutable(index);
+}
+inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() {
+  return service_.Add();
+}
+
+// repeated .google.protobuf.FieldDescriptorProto extension = 7;
+inline int FileDescriptorProto::extension_size() const {
+  return extension_.size();
+}
+inline void FileDescriptorProto::clear_extension() {
+  extension_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+FileDescriptorProto::extension() const {
+  return extension_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+FileDescriptorProto::mutable_extension() {
+  return &extension_;
+}
+inline const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const {
+  return extension_.Get(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
+  return extension_.Mutable(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() {
+  return extension_.Add();
+}
+
+// optional .google.protobuf.FileOptions options = 8;
+inline bool FileDescriptorProto::has_options() const {
+  return _has_bit(7);
+}
+inline void FileDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
+  _clear_bit(7);
+}
+inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
+  return options_ != NULL ? *options_ : *default_instance_.options_;
+}
+inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
+  _set_bit(7);
+  if (options_ == NULL) options_ = new ::google::protobuf::FileOptions;
+  return options_;
+}
+
+// -------------------------------------------------------------------
+
+// DescriptorProto_ExtensionRange
+
+// optional int32 start = 1;
+inline bool DescriptorProto_ExtensionRange::has_start() const {
+  return _has_bit(0);
+}
+inline void DescriptorProto_ExtensionRange::clear_start() {
+  start_ = 0;
+  _clear_bit(0);
+}
+inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const {
+  return start_;
+}
+inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) {
+  _set_bit(0);
+  start_ = value;
+}
+
+// optional int32 end = 2;
+inline bool DescriptorProto_ExtensionRange::has_end() const {
+  return _has_bit(1);
+}
+inline void DescriptorProto_ExtensionRange::clear_end() {
+  end_ = 0;
+  _clear_bit(1);
+}
+inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const {
+  return end_;
+}
+inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) {
+  _set_bit(1);
+  end_ = value;
+}
+
+// -------------------------------------------------------------------
+
+// DescriptorProto
+
+// optional string name = 1;
+inline bool DescriptorProto::has_name() const {
+  return _has_bit(0);
+}
+inline void DescriptorProto::clear_name() {
+  if (name_ != &_default_name_) {
+    name_->clear();
+  }
+  _clear_bit(0);
+}
+inline const ::std::string& DescriptorProto::name() const {
+  return *name_;
+}
+inline void DescriptorProto::set_name(const ::std::string& value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline void DescriptorProto::set_name(const char* value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline ::std::string* DescriptorProto::mutable_name() {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  return name_;
+}
+
+// repeated .google.protobuf.FieldDescriptorProto field = 2;
+inline int DescriptorProto::field_size() const {
+  return field_.size();
+}
+inline void DescriptorProto::clear_field() {
+  field_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::field() const {
+  return field_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+DescriptorProto::mutable_field() {
+  return &field_;
+}
+inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const {
+  return field_.Get(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
+  return field_.Mutable(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
+  return field_.Add();
+}
+
+// repeated .google.protobuf.FieldDescriptorProto extension = 6;
+inline int DescriptorProto::extension_size() const {
+  return extension_.size();
+}
+inline void DescriptorProto::clear_extension() {
+  extension_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::extension() const {
+  return extension_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+DescriptorProto::mutable_extension() {
+  return &extension_;
+}
+inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const {
+  return extension_.Get(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
+  return extension_.Mutable(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() {
+  return extension_.Add();
+}
+
+// repeated .google.protobuf.DescriptorProto nested_type = 3;
+inline int DescriptorProto::nested_type_size() const {
+  return nested_type_.size();
+}
+inline void DescriptorProto::clear_nested_type() {
+  nested_type_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+DescriptorProto::nested_type() const {
+  return nested_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+DescriptorProto::mutable_nested_type() {
+  return &nested_type_;
+}
+inline const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const {
+  return nested_type_.Get(index);
+}
+inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
+  return nested_type_.Mutable(index);
+}
+inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
+  return nested_type_.Add();
+}
+
+// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+inline int DescriptorProto::enum_type_size() const {
+  return enum_type_.size();
+}
+inline void DescriptorProto::clear_enum_type() {
+  enum_type_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+DescriptorProto::enum_type() const {
+  return enum_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+DescriptorProto::mutable_enum_type() {
+  return &enum_type_;
+}
+inline const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const {
+  return enum_type_.Get(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
+  return enum_type_.Mutable(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() {
+  return enum_type_.Add();
+}
+
+// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+inline int DescriptorProto::extension_range_size() const {
+  return extension_range_.size();
+}
+inline void DescriptorProto::clear_extension_range() {
+  extension_range_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
+DescriptorProto::extension_range() const {
+  return extension_range_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
+DescriptorProto::mutable_extension_range() {
+  return &extension_range_;
+}
+inline const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const {
+  return extension_range_.Get(index);
+}
+inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
+  return extension_range_.Mutable(index);
+}
+inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
+  return extension_range_.Add();
+}
+
+// optional .google.protobuf.MessageOptions options = 7;
+inline bool DescriptorProto::has_options() const {
+  return _has_bit(6);
+}
+inline void DescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
+  _clear_bit(6);
+}
+inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
+  return options_ != NULL ? *options_ : *default_instance_.options_;
+}
+inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
+  _set_bit(6);
+  if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions;
+  return options_;
+}
+
+// -------------------------------------------------------------------
+
+// FieldDescriptorProto
+
+// optional string name = 1;
+inline bool FieldDescriptorProto::has_name() const {
+  return _has_bit(0);
+}
+inline void FieldDescriptorProto::clear_name() {
+  if (name_ != &_default_name_) {
+    name_->clear();
+  }
+  _clear_bit(0);
+}
+inline const ::std::string& FieldDescriptorProto::name() const {
+  return *name_;
+}
+inline void FieldDescriptorProto::set_name(const ::std::string& value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline void FieldDescriptorProto::set_name(const char* value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline ::std::string* FieldDescriptorProto::mutable_name() {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  return name_;
+}
+
+// optional int32 number = 3;
+inline bool FieldDescriptorProto::has_number() const {
+  return _has_bit(1);
+}
+inline void FieldDescriptorProto::clear_number() {
+  number_ = 0;
+  _clear_bit(1);
+}
+inline ::google::protobuf::int32 FieldDescriptorProto::number() const {
+  return number_;
+}
+inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) {
+  _set_bit(1);
+  number_ = value;
+}
+
+// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+inline bool FieldDescriptorProto::has_label() const {
+  return _has_bit(2);
+}
+inline void FieldDescriptorProto::clear_label() {
+  label_ = 1;
+  _clear_bit(2);
+}
+inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
+  return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_);
+}
+inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
+  GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
+  _set_bit(2);
+  label_ = value;
+}
+
+// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+inline bool FieldDescriptorProto::has_type() const {
+  return _has_bit(3);
+}
+inline void FieldDescriptorProto::clear_type() {
+  type_ = 1;
+  _clear_bit(3);
+}
+inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
+  return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_);
+}
+inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
+  GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
+  _set_bit(3);
+  type_ = value;
+}
+
+// optional string type_name = 6;
+inline bool FieldDescriptorProto::has_type_name() const {
+  return _has_bit(4);
+}
+inline void FieldDescriptorProto::clear_type_name() {
+  if (type_name_ != &_default_type_name_) {
+    type_name_->clear();
+  }
+  _clear_bit(4);
+}
+inline const ::std::string& FieldDescriptorProto::type_name() const {
+  return *type_name_;
+}
+inline void FieldDescriptorProto::set_type_name(const ::std::string& value) {
+  _set_bit(4);
+  if (type_name_ == &_default_type_name_) {
+    type_name_ = new ::std::string;
+  }
+  type_name_->assign(value);
+}
+inline void FieldDescriptorProto::set_type_name(const char* value) {
+  _set_bit(4);
+  if (type_name_ == &_default_type_name_) {
+    type_name_ = new ::std::string;
+  }
+  type_name_->assign(value);
+}
+inline ::std::string* FieldDescriptorProto::mutable_type_name() {
+  _set_bit(4);
+  if (type_name_ == &_default_type_name_) {
+    type_name_ = new ::std::string;
+  }
+  return type_name_;
+}
+
+// optional string extendee = 2;
+inline bool FieldDescriptorProto::has_extendee() const {
+  return _has_bit(5);
+}
+inline void FieldDescriptorProto::clear_extendee() {
+  if (extendee_ != &_default_extendee_) {
+    extendee_->clear();
+  }
+  _clear_bit(5);
+}
+inline const ::std::string& FieldDescriptorProto::extendee() const {
+  return *extendee_;
+}
+inline void FieldDescriptorProto::set_extendee(const ::std::string& value) {
+  _set_bit(5);
+  if (extendee_ == &_default_extendee_) {
+    extendee_ = new ::std::string;
+  }
+  extendee_->assign(value);
+}
+inline void FieldDescriptorProto::set_extendee(const char* value) {
+  _set_bit(5);
+  if (extendee_ == &_default_extendee_) {
+    extendee_ = new ::std::string;
+  }
+  extendee_->assign(value);
+}
+inline ::std::string* FieldDescriptorProto::mutable_extendee() {
+  _set_bit(5);
+  if (extendee_ == &_default_extendee_) {
+    extendee_ = new ::std::string;
+  }
+  return extendee_;
+}
+
+// optional string default_value = 7;
+inline bool FieldDescriptorProto::has_default_value() const {
+  return _has_bit(6);
+}
+inline void FieldDescriptorProto::clear_default_value() {
+  if (default_value_ != &_default_default_value_) {
+    default_value_->clear();
+  }
+  _clear_bit(6);
+}
+inline const ::std::string& FieldDescriptorProto::default_value() const {
+  return *default_value_;
+}
+inline void FieldDescriptorProto::set_default_value(const ::std::string& value) {
+  _set_bit(6);
+  if (default_value_ == &_default_default_value_) {
+    default_value_ = new ::std::string;
+  }
+  default_value_->assign(value);
+}
+inline void FieldDescriptorProto::set_default_value(const char* value) {
+  _set_bit(6);
+  if (default_value_ == &_default_default_value_) {
+    default_value_ = new ::std::string;
+  }
+  default_value_->assign(value);
+}
+inline ::std::string* FieldDescriptorProto::mutable_default_value() {
+  _set_bit(6);
+  if (default_value_ == &_default_default_value_) {
+    default_value_ = new ::std::string;
+  }
+  return default_value_;
+}
+
+// optional .google.protobuf.FieldOptions options = 8;
+inline bool FieldDescriptorProto::has_options() const {
+  return _has_bit(7);
+}
+inline void FieldDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
+  _clear_bit(7);
+}
+inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
+  return options_ != NULL ? *options_ : *default_instance_.options_;
+}
+inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
+  _set_bit(7);
+  if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions;
+  return options_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumDescriptorProto
+
+// optional string name = 1;
+inline bool EnumDescriptorProto::has_name() const {
+  return _has_bit(0);
+}
+inline void EnumDescriptorProto::clear_name() {
+  if (name_ != &_default_name_) {
+    name_->clear();
+  }
+  _clear_bit(0);
+}
+inline const ::std::string& EnumDescriptorProto::name() const {
+  return *name_;
+}
+inline void EnumDescriptorProto::set_name(const ::std::string& value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline void EnumDescriptorProto::set_name(const char* value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline ::std::string* EnumDescriptorProto::mutable_name() {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  return name_;
+}
+
+// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+inline int EnumDescriptorProto::value_size() const {
+  return value_.size();
+}
+inline void EnumDescriptorProto::clear_value() {
+  value_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
+EnumDescriptorProto::value() const {
+  return value_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
+EnumDescriptorProto::mutable_value() {
+  return &value_;
+}
+inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const {
+  return value_.Get(index);
+}
+inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
+  return value_.Mutable(index);
+}
+inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
+  return value_.Add();
+}
+
+// optional .google.protobuf.EnumOptions options = 3;
+inline bool EnumDescriptorProto::has_options() const {
+  return _has_bit(2);
+}
+inline void EnumDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
+  _clear_bit(2);
+}
+inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
+  return options_ != NULL ? *options_ : *default_instance_.options_;
+}
+inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
+  _set_bit(2);
+  if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions;
+  return options_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumValueDescriptorProto
+
+// optional string name = 1;
+inline bool EnumValueDescriptorProto::has_name() const {
+  return _has_bit(0);
+}
+inline void EnumValueDescriptorProto::clear_name() {
+  if (name_ != &_default_name_) {
+    name_->clear();
+  }
+  _clear_bit(0);
+}
+inline const ::std::string& EnumValueDescriptorProto::name() const {
+  return *name_;
+}
+inline void EnumValueDescriptorProto::set_name(const ::std::string& value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline void EnumValueDescriptorProto::set_name(const char* value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline ::std::string* EnumValueDescriptorProto::mutable_name() {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  return name_;
+}
+
+// optional int32 number = 2;
+inline bool EnumValueDescriptorProto::has_number() const {
+  return _has_bit(1);
+}
+inline void EnumValueDescriptorProto::clear_number() {
+  number_ = 0;
+  _clear_bit(1);
+}
+inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const {
+  return number_;
+}
+inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) {
+  _set_bit(1);
+  number_ = value;
+}
+
+// optional .google.protobuf.EnumValueOptions options = 3;
+inline bool EnumValueDescriptorProto::has_options() const {
+  return _has_bit(2);
+}
+inline void EnumValueDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
+  _clear_bit(2);
+}
+inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
+  return options_ != NULL ? *options_ : *default_instance_.options_;
+}
+inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
+  _set_bit(2);
+  if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions;
+  return options_;
+}
+
+// -------------------------------------------------------------------
+
+// ServiceDescriptorProto
+
+// optional string name = 1;
+inline bool ServiceDescriptorProto::has_name() const {
+  return _has_bit(0);
+}
+inline void ServiceDescriptorProto::clear_name() {
+  if (name_ != &_default_name_) {
+    name_->clear();
+  }
+  _clear_bit(0);
+}
+inline const ::std::string& ServiceDescriptorProto::name() const {
+  return *name_;
+}
+inline void ServiceDescriptorProto::set_name(const ::std::string& value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline void ServiceDescriptorProto::set_name(const char* value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline ::std::string* ServiceDescriptorProto::mutable_name() {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  return name_;
+}
+
+// repeated .google.protobuf.MethodDescriptorProto method = 2;
+inline int ServiceDescriptorProto::method_size() const {
+  return method_.size();
+}
+inline void ServiceDescriptorProto::clear_method() {
+  method_.Clear();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
+ServiceDescriptorProto::method() const {
+  return method_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
+ServiceDescriptorProto::mutable_method() {
+  return &method_;
+}
+inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const {
+  return method_.Get(index);
+}
+inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
+  return method_.Mutable(index);
+}
+inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
+  return method_.Add();
+}
+
+// optional .google.protobuf.ServiceOptions options = 3;
+inline bool ServiceDescriptorProto::has_options() const {
+  return _has_bit(2);
+}
+inline void ServiceDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
+  _clear_bit(2);
+}
+inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
+  return options_ != NULL ? *options_ : *default_instance_.options_;
+}
+inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
+  _set_bit(2);
+  if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions;
+  return options_;
+}
+
+// -------------------------------------------------------------------
+
+// MethodDescriptorProto
+
+// optional string name = 1;
+inline bool MethodDescriptorProto::has_name() const {
+  return _has_bit(0);
+}
+inline void MethodDescriptorProto::clear_name() {
+  if (name_ != &_default_name_) {
+    name_->clear();
+  }
+  _clear_bit(0);
+}
+inline const ::std::string& MethodDescriptorProto::name() const {
+  return *name_;
+}
+inline void MethodDescriptorProto::set_name(const ::std::string& value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline void MethodDescriptorProto::set_name(const char* value) {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+}
+inline ::std::string* MethodDescriptorProto::mutable_name() {
+  _set_bit(0);
+  if (name_ == &_default_name_) {
+    name_ = new ::std::string;
+  }
+  return name_;
+}
+
+// optional string input_type = 2;
+inline bool MethodDescriptorProto::has_input_type() const {
+  return _has_bit(1);
+}
+inline void MethodDescriptorProto::clear_input_type() {
+  if (input_type_ != &_default_input_type_) {
+    input_type_->clear();
+  }
+  _clear_bit(1);
+}
+inline const ::std::string& MethodDescriptorProto::input_type() const {
+  return *input_type_;
+}
+inline void MethodDescriptorProto::set_input_type(const ::std::string& value) {
+  _set_bit(1);
+  if (input_type_ == &_default_input_type_) {
+    input_type_ = new ::std::string;
+  }
+  input_type_->assign(value);
+}
+inline void MethodDescriptorProto::set_input_type(const char* value) {
+  _set_bit(1);
+  if (input_type_ == &_default_input_type_) {
+    input_type_ = new ::std::string;
+  }
+  input_type_->assign(value);
+}
+inline ::std::string* MethodDescriptorProto::mutable_input_type() {
+  _set_bit(1);
+  if (input_type_ == &_default_input_type_) {
+    input_type_ = new ::std::string;
+  }
+  return input_type_;
+}
+
+// optional string output_type = 3;
+inline bool MethodDescriptorProto::has_output_type() const {
+  return _has_bit(2);
+}
+inline void MethodDescriptorProto::clear_output_type() {
+  if (output_type_ != &_default_output_type_) {
+    output_type_->clear();
+  }
+  _clear_bit(2);
+}
+inline const ::std::string& MethodDescriptorProto::output_type() const {
+  return *output_type_;
+}
+inline void MethodDescriptorProto::set_output_type(const ::std::string& value) {
+  _set_bit(2);
+  if (output_type_ == &_default_output_type_) {
+    output_type_ = new ::std::string;
+  }
+  output_type_->assign(value);
+}
+inline void MethodDescriptorProto::set_output_type(const char* value) {
+  _set_bit(2);
+  if (output_type_ == &_default_output_type_) {
+    output_type_ = new ::std::string;
+  }
+  output_type_->assign(value);
+}
+inline ::std::string* MethodDescriptorProto::mutable_output_type() {
+  _set_bit(2);
+  if (output_type_ == &_default_output_type_) {
+    output_type_ = new ::std::string;
+  }
+  return output_type_;
+}
+
+// optional .google.protobuf.MethodOptions options = 4;
+inline bool MethodDescriptorProto::has_options() const {
+  return _has_bit(3);
+}
+inline void MethodDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
+  _clear_bit(3);
+}
+inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
+  return options_ != NULL ? *options_ : *default_instance_.options_;
+}
+inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
+  _set_bit(3);
+  if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions;
+  return options_;
+}
+
+// -------------------------------------------------------------------
+
+// FileOptions
+
+// optional string java_package = 1;
+inline bool FileOptions::has_java_package() const {
+  return _has_bit(0);
+}
+inline void FileOptions::clear_java_package() {
+  if (java_package_ != &_default_java_package_) {
+    java_package_->clear();
+  }
+  _clear_bit(0);
+}
+inline const ::std::string& FileOptions::java_package() const {
+  return *java_package_;
+}
+inline void FileOptions::set_java_package(const ::std::string& value) {
+  _set_bit(0);
+  if (java_package_ == &_default_java_package_) {
+    java_package_ = new ::std::string;
+  }
+  java_package_->assign(value);
+}
+inline void FileOptions::set_java_package(const char* value) {
+  _set_bit(0);
+  if (java_package_ == &_default_java_package_) {
+    java_package_ = new ::std::string;
+  }
+  java_package_->assign(value);
+}
+inline ::std::string* FileOptions::mutable_java_package() {
+  _set_bit(0);
+  if (java_package_ == &_default_java_package_) {
+    java_package_ = new ::std::string;
+  }
+  return java_package_;
+}
+
+// optional string java_outer_classname = 8;
+inline bool FileOptions::has_java_outer_classname() const {
+  return _has_bit(1);
+}
+inline void FileOptions::clear_java_outer_classname() {
+  if (java_outer_classname_ != &_default_java_outer_classname_) {
+    java_outer_classname_->clear();
+  }
+  _clear_bit(1);
+}
+inline const ::std::string& FileOptions::java_outer_classname() const {
+  return *java_outer_classname_;
+}
+inline void FileOptions::set_java_outer_classname(const ::std::string& value) {
+  _set_bit(1);
+  if (java_outer_classname_ == &_default_java_outer_classname_) {
+    java_outer_classname_ = new ::std::string;
+  }
+  java_outer_classname_->assign(value);
+}
+inline void FileOptions::set_java_outer_classname(const char* value) {
+  _set_bit(1);
+  if (java_outer_classname_ == &_default_java_outer_classname_) {
+    java_outer_classname_ = new ::std::string;
+  }
+  java_outer_classname_->assign(value);
+}
+inline ::std::string* FileOptions::mutable_java_outer_classname() {
+  _set_bit(1);
+  if (java_outer_classname_ == &_default_java_outer_classname_) {
+    java_outer_classname_ = new ::std::string;
+  }
+  return java_outer_classname_;
+}
+
+// optional bool java_multiple_files = 10 [default = false];
+inline bool FileOptions::has_java_multiple_files() const {
+  return _has_bit(2);
+}
+inline void FileOptions::clear_java_multiple_files() {
+  java_multiple_files_ = false;
+  _clear_bit(2);
+}
+inline bool FileOptions::java_multiple_files() const {
+  return java_multiple_files_;
+}
+inline void FileOptions::set_java_multiple_files(bool value) {
+  _set_bit(2);
+  java_multiple_files_ = value;
+}
+
+// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = CODE_SIZE];
+inline bool FileOptions::has_optimize_for() const {
+  return _has_bit(3);
+}
+inline void FileOptions::clear_optimize_for() {
+  optimize_for_ = 2;
+  _clear_bit(3);
+}
+inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const {
+  return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_);
+}
+inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) {
+  GOOGLE_DCHECK(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
+  _set_bit(3);
+  optimize_for_ = value;
+}
+
+// -------------------------------------------------------------------
+
+// MessageOptions
+
+// optional bool message_set_wire_format = 1 [default = false];
+inline bool MessageOptions::has_message_set_wire_format() const {
+  return _has_bit(0);
+}
+inline void MessageOptions::clear_message_set_wire_format() {
+  message_set_wire_format_ = false;
+  _clear_bit(0);
+}
+inline bool MessageOptions::message_set_wire_format() const {
+  return message_set_wire_format_;
+}
+inline void MessageOptions::set_message_set_wire_format(bool value) {
+  _set_bit(0);
+  message_set_wire_format_ = value;
+}
+
+// -------------------------------------------------------------------
+
+// FieldOptions
+
+// optional .google.protobuf.FieldOptions.CType ctype = 1;
+inline bool FieldOptions::has_ctype() const {
+  return _has_bit(0);
+}
+inline void FieldOptions::clear_ctype() {
+  ctype_ = 1;
+  _clear_bit(0);
+}
+inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const {
+  return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_);
+}
+inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) {
+  GOOGLE_DCHECK(::google::protobuf::FieldOptions_CType_IsValid(value));
+  _set_bit(0);
+  ctype_ = value;
+}
+
+// optional string experimental_map_key = 9;
+inline bool FieldOptions::has_experimental_map_key() const {
+  return _has_bit(1);
+}
+inline void FieldOptions::clear_experimental_map_key() {
+  if (experimental_map_key_ != &_default_experimental_map_key_) {
+    experimental_map_key_->clear();
+  }
+  _clear_bit(1);
+}
+inline const ::std::string& FieldOptions::experimental_map_key() const {
+  return *experimental_map_key_;
+}
+inline void FieldOptions::set_experimental_map_key(const ::std::string& value) {
+  _set_bit(1);
+  if (experimental_map_key_ == &_default_experimental_map_key_) {
+    experimental_map_key_ = new ::std::string;
+  }
+  experimental_map_key_->assign(value);
+}
+inline void FieldOptions::set_experimental_map_key(const char* value) {
+  _set_bit(1);
+  if (experimental_map_key_ == &_default_experimental_map_key_) {
+    experimental_map_key_ = new ::std::string;
+  }
+  experimental_map_key_->assign(value);
+}
+inline ::std::string* FieldOptions::mutable_experimental_map_key() {
+  _set_bit(1);
+  if (experimental_map_key_ == &_default_experimental_map_key_) {
+    experimental_map_key_ = new ::std::string;
+  }
+  return experimental_map_key_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumOptions
+
+// -------------------------------------------------------------------
+
+// EnumValueOptions
+
+// -------------------------------------------------------------------
+
+// ServiceOptions
+
+// -------------------------------------------------------------------
+
+// MethodOptions
+
+
+}  // namespace protobuf
+}  // namespace google
+#endif  // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
new file mode 100644
index 0000000..13d9478
--- /dev/null
+++ b/src/google/protobuf/descriptor.proto
@@ -0,0 +1,286 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// The messages in this file describe the definitions found in .proto files.
+// A valid .proto file can be translated directly to a FileDescriptorProto
+// without any other information (e.g. without reading its imports).
+
+
+
+package google.protobuf;
+option java_package = "com.google.protobuf";
+option java_outer_classname = "DescriptorProtos";
+
+// descriptor.proto must be optimized for speed because reflection-based
+// algorithms don't work during bootstrapping.
+option optimize_for = SPEED;
+
+// Describes a complete .proto file.
+message FileDescriptorProto {
+  optional string name = 1;       // file name, relative to root of source tree
+  optional string package = 2;    // e.g. "foo", "foo.bar", etc.
+
+  // Names of files imported by this file.
+  repeated string dependency = 3;
+
+  // All top-level definitions in this file.
+  repeated DescriptorProto message_type = 4;
+  repeated EnumDescriptorProto enum_type = 5;
+  repeated ServiceDescriptorProto service = 6;
+  repeated FieldDescriptorProto extension = 7;
+
+  optional FileOptions options = 8;
+}
+
+// Describes a message type.
+message DescriptorProto {
+  optional string name = 1;
+
+  repeated FieldDescriptorProto field = 2;
+  repeated FieldDescriptorProto extension = 6;
+
+  repeated DescriptorProto nested_type = 3;
+  repeated EnumDescriptorProto enum_type = 4;
+
+  message ExtensionRange {
+    optional int32 start = 1;
+    optional int32 end = 2;
+  }
+  repeated ExtensionRange extension_range = 5;
+
+  optional MessageOptions options = 7;
+}
+
+// Describes a field within a message.
+message FieldDescriptorProto {
+  enum Type {
+    // 0 is reserved for errors.
+    // Order is weird for historical reasons.
+    TYPE_DOUBLE         = 1;
+    TYPE_FLOAT          = 2;
+    TYPE_INT64          = 3;   // Not ZigZag encoded.  Negative numbers
+                               // take 10 bytes.  Use TYPE_SINT64 if negative
+                               // values are likely.
+    TYPE_UINT64         = 4;
+    TYPE_INT32          = 5;   // Not ZigZag encoded.  Negative numbers
+                               // take 10 bytes.  Use TYPE_SINT32 if negative
+                               // values are likely.
+    TYPE_FIXED64        = 6;
+    TYPE_FIXED32        = 7;
+    TYPE_BOOL           = 8;
+    TYPE_STRING         = 9;
+    TYPE_GROUP          = 10;  // Tag-delimited aggregate.
+    TYPE_MESSAGE        = 11;  // Length-delimited aggregate.
+
+    // New in version 2.
+    TYPE_BYTES          = 12;
+    TYPE_UINT32         = 13;
+    TYPE_ENUM           = 14;
+    TYPE_SFIXED32       = 15;
+    TYPE_SFIXED64       = 16;
+    TYPE_SINT32         = 17;  // Uses ZigZag encoding.
+    TYPE_SINT64         = 18;  // Uses ZigZag encoding.
+  };
+
+  enum Label {
+    // 0 is reserved for errors
+    LABEL_OPTIONAL      = 1;
+    LABEL_REQUIRED      = 2;
+    LABEL_REPEATED      = 3;
+    // TODO(sanjay): Should we add LABEL_MAP?
+  };
+
+  optional string name = 1;
+  optional int32 number = 3;
+  optional Label label = 4;
+
+  // If type_name is set, this need not be set.  If both this and type_name
+  // are set, this must be either TYPE_ENUM or TYPE_MESSAGE.
+  optional Type type = 5;
+
+  // For message and enum types, this is the name of the type.  If the name
+  // starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
+  // rules are used to find the type (i.e. first the nested types within this
+  // message are searched, then within the parent, on up to the root
+  // namespace).
+  optional string type_name = 6;
+
+  // For extensions, this is the name of the type being extended.  It is
+  // resolved in the same manner as type_name.
+  optional string extendee = 2;
+
+  // For numeric types, contains the original text representation of the value.
+  // For booleans, "true" or "false".
+  // For strings, contains the default text contents (not escaped in any way).
+  // For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
+  // TODO(kenton):  Base-64 encode?
+  optional string default_value = 7;
+
+  optional FieldOptions options = 8;
+}
+
+// Describes an enum type.
+message EnumDescriptorProto {
+  optional string name = 1;
+
+  repeated EnumValueDescriptorProto value = 2;
+
+  optional EnumOptions options = 3;
+}
+
+// Describes a value within an enum.
+message EnumValueDescriptorProto {
+  optional string name = 1;
+  optional int32 number = 2;
+
+  optional EnumValueOptions options = 3;
+}
+
+// Describes a service.
+message ServiceDescriptorProto {
+  optional string name = 1;
+  repeated MethodDescriptorProto method = 2;
+
+  optional ServiceOptions options = 3;
+}
+
+// Describes a method of a service.
+message MethodDescriptorProto {
+  optional string name = 1;
+
+  // Input and output type names.  These are resolved in the same way as
+  // FieldDescriptorProto.type_name, but must refer to a message type.
+  optional string input_type = 2;
+  optional string output_type = 3;
+
+  optional MethodOptions options = 4;
+}
+
+// ===================================================================
+// Options
+
+// Each of the definitions above may have "options" attached.  These are
+// just annotations which may cause code to be generated slightly differently
+// or may contain hints for code that manipulates protocol messages.
+
+// TODO(kenton):  Allow extensions to options.
+
+message FileOptions {
+
+  // Sets the Java package where classes generated from this .proto will be
+  // placed.  By default, the proto package is used, but this is often
+  // inappropriate because proto packages do not normally start with backwards
+  // domain names.
+  optional string java_package = 1;
+
+
+  // If set, all the classes from the .proto file are wrapped in a single
+  // outer class with the given name.  This applies to both Proto1
+  // (equivalent to the old "--one_java_file" option) and Proto2 (where
+  // a .proto always translates to a single class, but you may want to
+  // explicitly choose the class name).
+  optional string java_outer_classname = 8;
+
+  // If set true, then the Java code generator will generate a separate .java
+  // file for each top-level message, enum, and service defined in the .proto
+  // file.  Thus, these types will *not* be nested inside the outer class
+  // named by java_outer_classname.  However, the outer class will still be
+  // generated to contain the file's getDescriptor() method as well as any
+  // top-level extensions defined in the file.
+  optional bool java_multiple_files = 10 [default=false];
+
+  // Generated classes can be optimized for speed or code size.
+  enum OptimizeMode {
+    SPEED = 1;      // Generate complete code for parsing, serialization, etc.
+    CODE_SIZE = 2;  // Use ReflectionOps to implement these methods.
+  }
+  optional OptimizeMode optimize_for = 9 [default=CODE_SIZE];
+}
+
+message MessageOptions {
+  // Set true to use the old proto1 MessageSet wire format for extensions.
+  // This is provided for backwards-compatibility with the MessageSet wire
+  // format.  You should not use this for any other reason:  It's less
+  // efficient, has fewer features, and is more complicated.
+  //
+  // The message must be defined exactly as follows:
+  //   message Foo {
+  //     option message_set_wire_format = true;
+  //     extensions 4 to max;
+  //   }
+  // Note that the message cannot have any defined fields; MessageSets only
+  // have extensions.
+  //
+  // All extensions of your type must be singular messages; e.g. they cannot
+  // be int32s, enums, or repeated messages.
+  //
+  // Because this is an option, the above two restrictions are not enforced by
+  // the protocol compiler.
+  optional bool message_set_wire_format = 1 [default=false];
+}
+
+message FieldOptions {
+  // The ctype option instructs the C++ code generator to use a different
+  // representation of the field than it normally would.  See the specific
+  // options below.  This option is not yet implemented in the open source
+  // release -- sorry, we'll try to include it in a future version!
+  optional CType ctype = 1;
+  enum CType {
+    CORD = 1;
+
+    STRING_PIECE = 2;
+  }
+
+  // EXPERIMENTAL.  DO NOT USE.
+  // For "map" fields, the name of the field in the enclosed type that
+  // is the key for this map.  For example, suppose we have:
+  //   message Item {
+  //     required string name = 1;
+  //     required string value = 2;
+  //   }
+  //   message Config {
+  //     repeated Item items = 1 [experimental_map_key="name"];
+  //   }
+  // In this situation, the map key for Item will be set to "name".
+  // TODO: Fully-implement this, then remove the "experimental_" prefix.
+  optional string experimental_map_key = 9;
+}
+
+message EnumOptions {
+}
+
+message EnumValueOptions {
+}
+
+message ServiceOptions {
+
+  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
+  //   framework.  We apologize for hoarding these numbers to ourselves, but
+  //   we were already using them long before we decided to release Protocol
+  //   Buffers.
+}
+
+message MethodOptions {
+
+  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
+  //   framework.  We apologize for hoarding these numbers to ourselves, but
+  //   we were already using them long before we decided to release Protocol
+  //   Buffers.
+}
diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc
new file mode 100644
index 0000000..944280c
--- /dev/null
+++ b/src/google/protobuf/descriptor_database.cc
@@ -0,0 +1,291 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/map-util.h>
+
+namespace google {
+namespace protobuf {
+
+DescriptorDatabase::~DescriptorDatabase() {}
+
+// ===================================================================
+
+SimpleDescriptorDatabase::SimpleDescriptorDatabase() {}
+SimpleDescriptorDatabase::~SimpleDescriptorDatabase() {
+  STLDeleteElements(&files_to_delete_);
+}
+
+void SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) {
+  FileDescriptorProto* new_file = new FileDescriptorProto;
+  new_file->CopyFrom(file);
+  AddAndOwn(new_file);
+}
+
+void SimpleDescriptorDatabase::AddAndOwn(const FileDescriptorProto* file) {
+  files_to_delete_.push_back(file);
+  InsertOrUpdate(&files_by_name_, file->name(), file);
+
+  string path = file->package();
+  if (!path.empty()) path += '.';
+
+  for (int i = 0; i < file->message_type_size(); i++) {
+    AddMessage(path, file->message_type(i), file);
+  }
+  for (int i = 0; i < file->enum_type_size(); i++) {
+    AddEnum(path, file->enum_type(i), file);
+  }
+  for (int i = 0; i < file->extension_size(); i++) {
+    AddField(path, file->extension(i), file);
+  }
+  for (int i = 0; i < file->service_size(); i++) {
+    AddService(path, file->service(i), file);
+  }
+}
+
+void SimpleDescriptorDatabase::AddMessage(
+    const string& path,
+    const DescriptorProto& message_type,
+    const FileDescriptorProto* file) {
+  string full_name = path + message_type.name();
+  InsertOrUpdate(&files_by_symbol_, full_name, file);
+
+  string sub_path = full_name + '.';
+  for (int i = 0; i < message_type.nested_type_size(); i++) {
+    AddMessage(sub_path, message_type.nested_type(i), file);
+  }
+  for (int i = 0; i < message_type.enum_type_size(); i++) {
+    AddEnum(sub_path, message_type.enum_type(i), file);
+  }
+  for (int i = 0; i < message_type.field_size(); i++) {
+    AddField(sub_path, message_type.field(i), file);
+  }
+  for (int i = 0; i < message_type.extension_size(); i++) {
+    AddField(sub_path, message_type.extension(i), file);
+  }
+}
+
+void SimpleDescriptorDatabase::AddField(
+    const string& path,
+    const FieldDescriptorProto& field,
+    const FileDescriptorProto* file) {
+  string full_name = path + field.name();
+  InsertOrUpdate(&files_by_symbol_, full_name, file);
+
+  if (field.has_extendee()) {
+    // This field is an extension.
+    if (!field.extendee().empty() && field.extendee()[0] == '.') {
+      // The extension is fully-qualified.  We can use it as a lookup key in
+      // the files_by_symbol_ table.
+      InsertOrUpdate(&files_by_extension_,
+                     make_pair(field.extendee().substr(1), field.number()),
+                     file);
+    } else {
+      // Not fully-qualified.  We can't really do anything here, unfortunately.
+    }
+  }
+}
+
+void SimpleDescriptorDatabase::AddEnum(
+    const string& path,
+    const EnumDescriptorProto& enum_type,
+    const FileDescriptorProto* file) {
+  string full_name = path + enum_type.name();
+  InsertOrUpdate(&files_by_symbol_, full_name, file);
+
+  string sub_path = full_name + '.';
+  for (int i = 0; i < enum_type.value_size(); i++) {
+    InsertOrUpdate(&files_by_symbol_,
+                   sub_path + enum_type.value(i).name(),
+                   file);
+  }
+}
+
+void SimpleDescriptorDatabase::AddService(
+    const string& path,
+    const ServiceDescriptorProto& service,
+    const FileDescriptorProto* file) {
+  string full_name = path + service.name();
+  InsertOrUpdate(&files_by_symbol_, full_name, file);
+
+  string sub_path = full_name + '.';
+  for (int i = 0; i < service.method_size(); i++) {
+    InsertOrUpdate(&files_by_symbol_,
+                   sub_path + service.method(i).name(),
+                   file);
+  }
+}
+
+bool SimpleDescriptorDatabase::FindFileByName(
+    const string& filename,
+    FileDescriptorProto* output) {
+  const FileDescriptorProto* result = FindPtrOrNull(files_by_name_, filename);
+  if (result == NULL) {
+    return false;
+  } else {
+    output->CopyFrom(*result);
+    return true;
+  }
+}
+
+bool SimpleDescriptorDatabase::FindFileContainingSymbol(
+    const string& symbol_name,
+    FileDescriptorProto* output) {
+  const FileDescriptorProto* result =
+    FindPtrOrNull(files_by_symbol_, symbol_name);
+  if (result == NULL) {
+    return false;
+  } else {
+    output->CopyFrom(*result);
+    return true;
+  }
+}
+
+bool SimpleDescriptorDatabase::FindFileContainingExtension(
+    const string& containing_type,
+    int field_number,
+    FileDescriptorProto* output) {
+  const FileDescriptorProto* result =
+    FindPtrOrNull(files_by_extension_,
+                  make_pair(containing_type, field_number));
+  if (result == NULL) {
+    return false;
+  } else {
+    output->CopyFrom(*result);
+    return true;
+  }
+}
+
+// ===================================================================
+
+DescriptorPoolDatabase::DescriptorPoolDatabase(const DescriptorPool& pool)
+  : pool_(pool) {}
+DescriptorPoolDatabase::~DescriptorPoolDatabase() {}
+
+bool DescriptorPoolDatabase::FindFileByName(
+    const string& filename,
+    FileDescriptorProto* output) {
+  const FileDescriptor* file = pool_.FindFileByName(filename);
+  if (file == NULL) return false;
+  output->Clear();
+  file->CopyTo(output);
+  return true;
+}
+
+bool DescriptorPoolDatabase::FindFileContainingSymbol(
+    const string& symbol_name,
+    FileDescriptorProto* output) {
+  const FileDescriptor* file = pool_.FindFileContainingSymbol(symbol_name);
+  if (file == NULL) return false;
+  output->Clear();
+  file->CopyTo(output);
+  return true;
+}
+
+bool DescriptorPoolDatabase::FindFileContainingExtension(
+    const string& containing_type,
+    int field_number,
+    FileDescriptorProto* output) {
+  const Descriptor* extendee = pool_.FindMessageTypeByName(containing_type);
+  if (extendee == NULL) return false;
+
+  const FieldDescriptor* extension =
+    pool_.FindExtensionByNumber(extendee, field_number);
+  if (extension == NULL) return false;
+
+  output->Clear();
+  extension->file()->CopyTo(output);
+  return true;
+}
+
+// ===================================================================
+
+MergedDescriptorDatabase::MergedDescriptorDatabase(
+    DescriptorDatabase* source1,
+    DescriptorDatabase* source2) {
+  sources_.push_back(source1);
+  sources_.push_back(source2);
+}
+MergedDescriptorDatabase::MergedDescriptorDatabase(
+    const vector<DescriptorDatabase*>& sources)
+  : sources_(sources) {}
+MergedDescriptorDatabase::~MergedDescriptorDatabase() {}
+
+bool MergedDescriptorDatabase::FindFileByName(
+    const string& filename,
+    FileDescriptorProto* output) {
+  for (int i = 0; i < sources_.size(); i++) {
+    if (sources_[i]->FindFileByName(filename, output)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool MergedDescriptorDatabase::FindFileContainingSymbol(
+    const string& symbol_name,
+    FileDescriptorProto* output) {
+  for (int i = 0; i < sources_.size(); i++) {
+    if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) {
+      // The symbol was found in source i.  However, if one of the previous
+      // sources defines a file with the same name (which presumably doesn't
+      // contain the symbol, since it wasn't found in that source), then we
+      // must hide it from the caller.
+      FileDescriptorProto temp;
+      for (int j = 0; j < i; j++) {
+        if (sources_[j]->FindFileByName(output->name(), &temp)) {
+          // Found conflicting file in a previous source.
+          return false;
+        }
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+bool MergedDescriptorDatabase::FindFileContainingExtension(
+    const string& containing_type,
+    int field_number,
+    FileDescriptorProto* output) {
+  for (int i = 0; i < sources_.size(); i++) {
+    if (sources_[i]->FindFileContainingExtension(
+          containing_type, field_number, output)) {
+      // The symbol was found in source i.  However, if one of the previous
+      // sources defines a file with the same name (which presumably doesn't
+      // contain the symbol, since it wasn't found in that source), then we
+      // must hide it from the caller.
+      FileDescriptorProto temp;
+      for (int j = 0; j < i; j++) {
+        if (sources_[j]->FindFileByName(output->name(), &temp)) {
+          // Found conflicting file in a previous source.
+          return false;
+        }
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h
new file mode 100644
index 0000000..d629da4
--- /dev/null
+++ b/src/google/protobuf/descriptor_database.h
@@ -0,0 +1,183 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Interface for manipulating databases of descriptors.
+
+#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
+#define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+
+// Abstract interface for a database of descriptors.
+//
+// This is useful if you want to create a DescriptorPool which loads
+// descriptors on-demand from some sort of large database.  If the database
+// is large, it may be inefficient to enumerate every .proto file inside it
+// calling DescriptorPool::BuildFile() for each one.  Instead, a DescriptorPool
+// can be created which wraps a DescriptorDatabase and only builds particular
+// descriptors when they are needed.
+class LIBPROTOBUF_EXPORT DescriptorDatabase {
+ public:
+  inline DescriptorDatabase() {}
+  virtual ~DescriptorDatabase();
+
+  // Find a file by file name.  Fills in in *output and returns true if found.
+  // Otherwise, returns false, leaving the contents of *output undefined.
+  virtual bool FindFileByName(const string& filename,
+                              FileDescriptorProto* output) = 0;
+
+  // Find the file that declares the given fully-qualified symbol name.
+  // If found, fills in *output and returns true, otherwise returns false
+  // and leaves *output undefined.
+  virtual bool FindFileContainingSymbol(const string& symbol_name,
+                                        FileDescriptorProto* output) = 0;
+
+  // Find the file which defines an extension extending the given message type
+  // with the given field number.  If found, fills in *output and returns true,
+  // otherwise returns false and leaves *output undefined.  containing_type
+  // must be a fully-qualified type name.
+  virtual bool FindFileContainingExtension(const string& containing_type,
+                                           int field_number,
+                                           FileDescriptorProto* output) = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase);
+};
+
+// A DescriptorDatabase into which you can insert files manually.
+//
+// FindFileContainingSymbol() is fully-implemented.  When you add a file, its
+// symbols will be indexed for this purpose.
+//
+// FindFileContainingExtension() is mostly-implemented.  It works if and only
+// if the original FieldDescriptorProto defining the extension has a
+// fully-qualified type name in its "extendee" field (i.e. starts with a '.').
+// If the extendee is a relative name, SimpleDescriptorDatabase will not
+// attempt to resolve the type, so it will not know what type the extension is
+// extending.  Therefore, calling FindFileContainingExtension() with the
+// extension's containing type will never actually find that extension.  Note
+// that this is an unlikely problem, as all FileDescriptorProtos created by the
+// protocol compiler (as well as ones created by calling
+// FileDescriptor::CopyTo()) will always use fully-qualified names for all
+// types.  You only need to worry if you are constructing FileDescriptorProtos
+// yourself, or are calling compiler::Parser directly.
+class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
+ public:
+  SimpleDescriptorDatabase();
+  ~SimpleDescriptorDatabase();
+
+  // Adds the FileDescriptorProto to the database, making a copy.  The object
+  // can be deleted after Add() returns.
+  void Add(const FileDescriptorProto& file);
+
+  // Adds the FileDescriptorProto to the database and takes ownership of it.
+  void AddAndOwn(const FileDescriptorProto* file);
+
+  // implements DescriptorDatabase -----------------------------------
+  bool FindFileByName(const string& filename,
+                      FileDescriptorProto* output);
+  bool FindFileContainingSymbol(const string& symbol_name,
+                                FileDescriptorProto* output);
+  bool FindFileContainingExtension(const string& containing_type,
+                                   int field_number,
+                                   FileDescriptorProto* output);
+
+ private:
+  // Helpers to recursively add particular descriptors and all their contents
+  // to the by-symbol and by-extension tables.
+  void AddMessage(const string& path,
+                  const DescriptorProto& message_type,
+                  const FileDescriptorProto* file);
+  void AddField(const string& path,
+                const FieldDescriptorProto& field,
+                const FileDescriptorProto* file);
+  void AddEnum(const string& path,
+               const EnumDescriptorProto& enum_type,
+               const FileDescriptorProto* file);
+  void AddService(const string& path,
+                  const ServiceDescriptorProto& service,
+                  const FileDescriptorProto* file);
+
+  vector<const FileDescriptorProto*> files_to_delete_;
+  map<string, const FileDescriptorProto*> files_by_name_;
+  map<string, const FileDescriptorProto*> files_by_symbol_;
+  map<pair<string, int>, const FileDescriptorProto*> files_by_extension_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase);
+};
+
+// A DescriptorDatabase that fetches files from a given pool.
+class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase {
+ public:
+  DescriptorPoolDatabase(const DescriptorPool& pool);
+  ~DescriptorPoolDatabase();
+
+  // implements DescriptorDatabase -----------------------------------
+  bool FindFileByName(const string& filename,
+                      FileDescriptorProto* output);
+  bool FindFileContainingSymbol(const string& symbol_name,
+                                FileDescriptorProto* output);
+  bool FindFileContainingExtension(const string& containing_type,
+                                   int field_number,
+                                   FileDescriptorProto* output);
+
+ private:
+  const DescriptorPool& pool_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPoolDatabase);
+};
+
+// A DescriptorDatabase that wraps two or more others.  It first searches the
+// first database and, if that fails, tries the second, and so on.
+class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
+ public:
+  // Merge just two databases.  The sources remain property of the caller.
+  MergedDescriptorDatabase(DescriptorDatabase* source1,
+                           DescriptorDatabase* source2);
+  // Merge more than two databases.  The sources remain property of the caller.
+  // The vector may be deleted after the constructor returns but the
+  // DescriptorDatabases need to stick around.
+  MergedDescriptorDatabase(const vector<DescriptorDatabase*>& sources);
+  ~MergedDescriptorDatabase();
+
+  // implements DescriptorDatabase -----------------------------------
+  bool FindFileByName(const string& filename,
+                      FileDescriptorProto* output);
+  bool FindFileContainingSymbol(const string& symbol_name,
+                                FileDescriptorProto* output);
+  bool FindFileContainingExtension(const string& containing_type,
+                                   int field_number,
+                                   FileDescriptorProto* output);
+
+ private:
+  vector<DescriptorDatabase*> sources_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc
new file mode 100644
index 0000000..cbbf592
--- /dev/null
+++ b/src/google/protobuf/descriptor_database_unittest.cc
@@ -0,0 +1,601 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file makes extensive use of RFC 3092.  :)
+
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/stubs/strutil.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+static bool AddToPool(DescriptorPool* pool, const char* file_text) {
+  FileDescriptorProto file_proto;
+  if (!TextFormat::ParseFromString(file_text, &file_proto)) return false;
+  if (pool->BuildFile(file_proto) == NULL) return false;
+  return true;
+}
+
+static void AddToDatabase(SimpleDescriptorDatabase* database,
+                          const char* file_text) {
+  FileDescriptorProto file_proto;
+  EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+  database->Add(file_proto);
+}
+
+static void ExpectContainsType(const FileDescriptorProto& proto,
+                               const string& type_name) {
+  for (int i = 0; i < proto.message_type_size(); i++) {
+    if (proto.message_type(i).name() == type_name) return;
+  }
+  ADD_FAILURE() << "\"" << proto.name()
+                << "\" did not contain expected type \""
+                << type_name << "\".";
+}
+
+// ===================================================================
+
+TEST(SimpleDescriptorDatabaseTest, FindFileByName) {
+  SimpleDescriptorDatabase database;
+  AddToDatabase(&database,
+    "name: \"foo.proto\" "
+    "message_type { name:\"Foo\" }");
+  AddToDatabase(&database,
+    "name: \"bar.proto\" "
+    "message_type { name:\"Bar\" }");
+
+  {
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileByName("foo.proto", &file));
+    EXPECT_EQ("foo.proto", file.name());
+    ExpectContainsType(file, "Foo");
+  }
+
+  {
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileByName("bar.proto", &file));
+    EXPECT_EQ("bar.proto", file.name());
+    ExpectContainsType(file, "Bar");
+  }
+
+  {
+    // Fails to find undefined files.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileByName("baz.proto", &file));
+  }
+}
+
+TEST(SimpleDescriptorDatabaseTest, FindFileContainingSymbol) {
+  SimpleDescriptorDatabase database;
+  AddToDatabase(&database,
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"Foo\" "
+    "  field { name:\"qux\" }"
+    "  nested_type { name: \"Grault\" } "
+    "  enum_type { name: \"Garply\" } "
+    "} "
+    "enum_type { "
+    "  name: \"Waldo\" "
+    "  value { name:\"FRED\" } "
+    "} "
+    "extension { name: \"plugh\" } "
+    "service { "
+    "  name: \"Xyzzy\" "
+    "  method { name: \"Thud\" } "
+    "}"
+    );
+  AddToDatabase(&database,
+    "name: \"bar.proto\" "
+    "package: \"corge\" "
+    "message_type { name: \"Bar\" }");
+
+  {
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("Foo", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find fields.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("Foo.qux", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find nested types.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("Foo.Grault", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find nested enums.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("Foo.Garply", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find enum types.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("Waldo", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find enum values.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("Waldo.FRED", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find extensions.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("plugh", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find services.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("Xyzzy", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find methods.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("Xyzzy.Thud", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find things in packages.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("corge.Bar", &file));
+    EXPECT_EQ("bar.proto", file.name());
+  }
+
+  {
+    // Fails to find undefined symbols.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingSymbol("Baz", &file));
+  }
+
+  {
+    // Names must be fully-qualified.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingSymbol("Bar", &file));
+  }
+}
+
+TEST(SimpleDescriptorDatabaseTest, FindFileContainingExtension) {
+  SimpleDescriptorDatabase database;
+  AddToDatabase(&database,
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"Foo\" "
+    "  extension_range { start: 1 end: 1000 } "
+    "  extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
+    "              extendee: \".Foo\" }"
+    "}");
+  AddToDatabase(&database,
+    "name: \"bar.proto\" "
+    "package: \"corge\" "
+    "dependency: \"foo.proto\" "
+    "message_type { "
+    "  name: \"Bar\" "
+    "  extension_range { start: 1 end: 1000 } "
+    "} "
+    "extension { name:\"grault\" extendee: \".Foo\"       number:32 } "
+    "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } "
+    "extension { name:\"waldo\"  extendee: \"Bar\"        number:56 } ");
+
+  {
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingExtension("Foo", 5, &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingExtension("Foo", 32, &file));
+    EXPECT_EQ("bar.proto", file.name());
+  }
+
+  {
+    // Can find extensions for qualified type names.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingExtension("corge.Bar", 70, &file));
+    EXPECT_EQ("bar.proto", file.name());
+  }
+
+  {
+    // Can't find extensions whose extendee was not fully-qualified in the
+    // FileDescriptorProto.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingExtension("Bar", 56, &file));
+    EXPECT_FALSE(database.FindFileContainingExtension("corge.Bar", 56, &file));
+  }
+
+  {
+    // Can't find non-existent extension numbers.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingExtension("Foo", 12, &file));
+  }
+
+  {
+    // Can't find extensions for non-existent types.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingExtension("NoSuchType", 5, &file));
+  }
+
+  {
+    // Can't find extensions for unqualified type names.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingExtension("Bar", 70, &file));
+  }
+}
+
+// ===================================================================
+
+TEST(DescriptorPoolDatabaseTest, FindFileByName) {
+  DescriptorPool pool;
+  ASSERT_TRUE(AddToPool(&pool,
+    "name: \"foo.proto\" "
+    "message_type { name:\"Foo\" }"));
+  ASSERT_TRUE(AddToPool(&pool,
+    "name: \"bar.proto\" "
+    "message_type { name:\"Bar\" }"));
+
+  DescriptorPoolDatabase database(pool);
+
+  {
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileByName("foo.proto", &file));
+    EXPECT_EQ("foo.proto", file.name());
+    ExpectContainsType(file, "Foo");
+  }
+
+  {
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileByName("bar.proto", &file));
+    EXPECT_EQ("bar.proto", file.name());
+    ExpectContainsType(file, "Bar");
+  }
+
+  {
+    // Fails to find undefined files.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileByName("baz.proto", &file));
+  }
+}
+
+TEST(DescriptorPoolDatabaseTest, FindFileContainingSymbol) {
+  DescriptorPool pool;
+  ASSERT_TRUE(AddToPool(&pool,
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"Foo\" "
+    "  field { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
+    "}"));
+  ASSERT_TRUE(AddToPool(&pool,
+    "name: \"bar.proto\" "
+    "package: \"corge\" "
+    "message_type { name: \"Bar\" }"));
+
+  DescriptorPoolDatabase database(pool);
+
+  {
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("Foo", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find fields.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("Foo.qux", &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    // Can find things in packages.
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingSymbol("corge.Bar", &file));
+    EXPECT_EQ("bar.proto", file.name());
+  }
+
+  {
+    // Fails to find undefined symbols.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingSymbol("Baz", &file));
+  }
+
+  {
+    // Names must be fully-qualified.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingSymbol("Bar", &file));
+  }
+}
+
+TEST(DescriptorPoolDatabaseTest, FindFileContainingExtension) {
+  DescriptorPool pool;
+  ASSERT_TRUE(AddToPool(&pool,
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"Foo\" "
+    "  extension_range { start: 1 end: 1000 } "
+    "  extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
+    "              extendee: \"Foo\" }"
+    "}"));
+  ASSERT_TRUE(AddToPool(&pool,
+    "name: \"bar.proto\" "
+    "package: \"corge\" "
+    "dependency: \"foo.proto\" "
+    "message_type { "
+    "  name: \"Bar\" "
+    "  extension_range { start: 1 end: 1000 } "
+    "} "
+    "extension { name:\"grault\" label:LABEL_OPTIONAL type:TYPE_BOOL number:32 "
+    "            extendee: \"Foo\" } "
+    "extension { name:\"garply\" label:LABEL_OPTIONAL type:TYPE_BOOL number:70 "
+    "            extendee: \"Bar\" } "));
+
+  DescriptorPoolDatabase database(pool);
+
+  {
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingExtension("Foo", 5, &file));
+    EXPECT_EQ("foo.proto", file.name());
+  }
+
+  {
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingExtension("Foo", 32, &file));
+    EXPECT_EQ("bar.proto", file.name());
+  }
+
+  {
+    // Can find extensions for qualified type names..
+    FileDescriptorProto file;
+    EXPECT_TRUE(database.FindFileContainingExtension("corge.Bar", 70, &file));
+    EXPECT_EQ("bar.proto", file.name());
+  }
+
+  {
+    // Can't find non-existent extension numbers.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingExtension("Foo", 12, &file));
+  }
+
+  {
+    // Can't find extensions for non-existent types.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingExtension("NoSuchType", 5, &file));
+  }
+
+  {
+    // Can't find extensions for unqualified type names.
+    FileDescriptorProto file;
+    EXPECT_FALSE(database.FindFileContainingExtension("Bar", 70, &file));
+  }
+}
+
+// ===================================================================
+
+class MergedDescriptorDatabaseTest : public testing::Test {
+ protected:
+  MergedDescriptorDatabaseTest()
+    : forward_merged_(&database1_, &database2_),
+      reverse_merged_(&database2_, &database1_) {}
+
+  virtual void SetUp() {
+    AddToDatabase(&database1_,
+      "name: \"foo.proto\" "
+      "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } "
+      "extension { name:\"foo_ext\" extendee: \".Foo\" number:3 "
+      "            label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+    AddToDatabase(&database2_,
+      "name: \"bar.proto\" "
+      "message_type { name:\"Bar\" extension_range { start: 1 end: 100 } } "
+      "extension { name:\"bar_ext\" extendee: \".Bar\" number:5 "
+      "            label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+
+    // baz.proto exists in both pools, with different definitions.
+    AddToDatabase(&database1_,
+      "name: \"baz.proto\" "
+      "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } "
+      "message_type { name:\"FromPool1\" } "
+      "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 "
+      "            label:LABEL_OPTIONAL type:TYPE_INT32 } "
+      "extension { name:\"database1_only_ext\" extendee: \".Baz\" number:13 "
+      "            label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+    AddToDatabase(&database2_,
+      "name: \"baz.proto\" "
+      "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } "
+      "message_type { name:\"FromPool2\" } "
+      "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 "
+      "            label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+  }
+
+  SimpleDescriptorDatabase database1_;
+  SimpleDescriptorDatabase database2_;
+
+  MergedDescriptorDatabase forward_merged_;
+  MergedDescriptorDatabase reverse_merged_;
+};
+
+TEST_F(MergedDescriptorDatabaseTest, FindFileByName) {
+  {
+    // Can find file that is only in database1_.
+    FileDescriptorProto file;
+    EXPECT_TRUE(forward_merged_.FindFileByName("foo.proto", &file));
+    EXPECT_EQ("foo.proto", file.name());
+    ExpectContainsType(file, "Foo");
+  }
+
+  {
+    // Can find file that is only in database2_.
+    FileDescriptorProto file;
+    EXPECT_TRUE(forward_merged_.FindFileByName("bar.proto", &file));
+    EXPECT_EQ("bar.proto", file.name());
+    ExpectContainsType(file, "Bar");
+  }
+
+  {
+    // In forward_merged_, database1_'s baz.proto takes precedence.
+    FileDescriptorProto file;
+    EXPECT_TRUE(forward_merged_.FindFileByName("baz.proto", &file));
+    EXPECT_EQ("baz.proto", file.name());
+    ExpectContainsType(file, "FromPool1");
+  }
+
+  {
+    // In reverse_merged_, database2_'s baz.proto takes precedence.
+    FileDescriptorProto file;
+    EXPECT_TRUE(reverse_merged_.FindFileByName("baz.proto", &file));
+    EXPECT_EQ("baz.proto", file.name());
+    ExpectContainsType(file, "FromPool2");
+  }
+
+  {
+    // Can't find non-existent file.
+    FileDescriptorProto file;
+    EXPECT_FALSE(forward_merged_.FindFileByName("no_such.proto", &file));
+  }
+}
+
+TEST_F(MergedDescriptorDatabaseTest, FindFileContainingSymbol) {
+  {
+    // Can find file that is only in database1_.
+    FileDescriptorProto file;
+    EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Foo", &file));
+    EXPECT_EQ("foo.proto", file.name());
+    ExpectContainsType(file, "Foo");
+  }
+
+  {
+    // Can find file that is only in database2_.
+    FileDescriptorProto file;
+    EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Bar", &file));
+    EXPECT_EQ("bar.proto", file.name());
+    ExpectContainsType(file, "Bar");
+  }
+
+  {
+    // In forward_merged_, database1_'s baz.proto takes precedence.
+    FileDescriptorProto file;
+    EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Baz", &file));
+    EXPECT_EQ("baz.proto", file.name());
+    ExpectContainsType(file, "FromPool1");
+  }
+
+  {
+    // In reverse_merged_, database2_'s baz.proto takes precedence.
+    FileDescriptorProto file;
+    EXPECT_TRUE(reverse_merged_.FindFileContainingSymbol("Baz", &file));
+    EXPECT_EQ("baz.proto", file.name());
+    ExpectContainsType(file, "FromPool2");
+  }
+
+  {
+    // FromPool1 only shows up in forward_merged_ because it is masked by
+    // database2_'s baz.proto in reverse_merged_.
+    FileDescriptorProto file;
+    EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("FromPool1", &file));
+    EXPECT_FALSE(reverse_merged_.FindFileContainingSymbol("FromPool1", &file));
+  }
+
+  {
+    // Can't find non-existent symbol.
+    FileDescriptorProto file;
+    EXPECT_FALSE(
+      forward_merged_.FindFileContainingSymbol("NoSuchType", &file));
+  }
+}
+
+TEST_F(MergedDescriptorDatabaseTest, FindFileContainingExtension) {
+  {
+    // Can find file that is only in database1_.
+    FileDescriptorProto file;
+    EXPECT_TRUE(
+      forward_merged_.FindFileContainingExtension("Foo", 3, &file));
+    EXPECT_EQ("foo.proto", file.name());
+    ExpectContainsType(file, "Foo");
+  }
+
+  {
+    // Can find file that is only in database2_.
+    FileDescriptorProto file;
+    EXPECT_TRUE(
+      forward_merged_.FindFileContainingExtension("Bar", 5, &file));
+    EXPECT_EQ("bar.proto", file.name());
+    ExpectContainsType(file, "Bar");
+  }
+
+  {
+    // In forward_merged_, database1_'s baz.proto takes precedence.
+    FileDescriptorProto file;
+    EXPECT_TRUE(
+      forward_merged_.FindFileContainingExtension("Baz", 12, &file));
+    EXPECT_EQ("baz.proto", file.name());
+    ExpectContainsType(file, "FromPool1");
+  }
+
+  {
+    // In reverse_merged_, database2_'s baz.proto takes precedence.
+    FileDescriptorProto file;
+    EXPECT_TRUE(
+      reverse_merged_.FindFileContainingExtension("Baz", 12, &file));
+    EXPECT_EQ("baz.proto", file.name());
+    ExpectContainsType(file, "FromPool2");
+  }
+
+  {
+    // Baz's extension 13 only shows up in forward_merged_ because it is
+    // masked by database2_'s baz.proto in reverse_merged_.
+    FileDescriptorProto file;
+    EXPECT_TRUE(forward_merged_.FindFileContainingExtension("Baz", 13, &file));
+    EXPECT_FALSE(reverse_merged_.FindFileContainingExtension("Baz", 13, &file));
+  }
+
+  {
+    // Can't find non-existent extension.
+    FileDescriptorProto file;
+    EXPECT_FALSE(
+      forward_merged_.FindFileContainingExtension("Foo", 6, &file));
+  }
+}
+
+}  // anonymous namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
new file mode 100644
index 0000000..18397a6
--- /dev/null
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -0,0 +1,2634 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file makes extensive use of RFC 3092.  :)
+
+#include <vector>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+// Some helpers to make assembling descriptors faster.
+DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) {
+  DescriptorProto* result = file->add_message_type();
+  result->set_name(name);
+  return result;
+}
+
+DescriptorProto* AddNestedMessage(DescriptorProto* parent, const string& name) {
+  DescriptorProto* result = parent->add_nested_type();
+  result->set_name(name);
+  return result;
+}
+
+EnumDescriptorProto* AddEnum(FileDescriptorProto* file, const string& name) {
+  EnumDescriptorProto* result = file->add_enum_type();
+  result->set_name(name);
+  return result;
+}
+
+EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent,
+                                   const string& name) {
+  EnumDescriptorProto* result = parent->add_enum_type();
+  result->set_name(name);
+  return result;
+}
+
+ServiceDescriptorProto* AddService(FileDescriptorProto* file,
+                                   const string& name) {
+  ServiceDescriptorProto* result = file->add_service();
+  result->set_name(name);
+  return result;
+}
+
+FieldDescriptorProto* AddField(DescriptorProto* parent,
+                               const string& name, int number,
+                               FieldDescriptorProto::Label label,
+                               FieldDescriptorProto::Type type) {
+  FieldDescriptorProto* result = parent->add_field();
+  result->set_name(name);
+  result->set_number(number);
+  result->set_label(label);
+  result->set_type(type);
+  return result;
+}
+
+FieldDescriptorProto* AddExtension(FileDescriptorProto* file,
+                                   const string& extendee,
+                                   const string& name, int number,
+                                   FieldDescriptorProto::Label label,
+                                   FieldDescriptorProto::Type type) {
+  FieldDescriptorProto* result = file->add_extension();
+  result->set_name(name);
+  result->set_number(number);
+  result->set_label(label);
+  result->set_type(type);
+  result->set_extendee(extendee);
+  return result;
+}
+
+FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent,
+                                         const string& extendee,
+                                         const string& name, int number,
+                                         FieldDescriptorProto::Label label,
+                                         FieldDescriptorProto::Type type) {
+  FieldDescriptorProto* result = parent->add_extension();
+  result->set_name(name);
+  result->set_number(number);
+  result->set_label(label);
+  result->set_type(type);
+  result->set_extendee(extendee);
+  return result;
+}
+
+DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent,
+                                                   int start, int end) {
+  DescriptorProto::ExtensionRange* result = parent->add_extension_range();
+  result->set_start(start);
+  result->set_end(end);
+  return result;
+}
+
+EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto,
+                                       const string& name, int number) {
+  EnumValueDescriptorProto* result = enum_proto->add_value();
+  result->set_name(name);
+  result->set_number(number);
+  return result;
+}
+
+MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service,
+                                 const string& name,
+                                 const string& input_type,
+                                 const string& output_type) {
+  MethodDescriptorProto* result = service->add_method();
+  result->set_name(name);
+  result->set_input_type(input_type);
+  result->set_output_type(output_type);
+  return result;
+}
+
+// Empty enums technically aren't allowed.  We need to insert a dummy value
+// into them.
+void AddEmptyEnum(FileDescriptorProto* file, const string& name) {
+  AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1);
+}
+
+// ===================================================================
+
+// Test simple files.
+class FileDescriptorTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    // Build descriptors for the following definitions:
+    //
+    //   // in "foo.proto"
+    //   message FooMessage { extensions 1; }
+    //   enum FooEnum {FOO_ENUM_VALUE = 1;}
+    //   service FooService {}
+    //   extend FooMessage { optional int32 foo_extension = 1; }
+    //
+    //   // in "bar.proto"
+    //   package bar_package;
+    //   message BarMessage { extensions 1; }
+    //   enum BarEnum {BAR_ENUM_VALUE = 1;}
+    //   service BarService {}
+    //   extend BarMessage { optional int32 bar_extension = 1; }
+    //
+    // Also, we have an empty file "baz.proto".  This file's purpose is to
+    // make sure that even though it has the same package as foo.proto,
+    // searching it for members of foo.proto won't work.
+
+    FileDescriptorProto foo_file;
+    foo_file.set_name("foo.proto");
+    AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2);
+    AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1);
+    AddService(&foo_file, "FooService");
+    AddExtension(&foo_file, "FooMessage", "foo_extension", 1,
+                 FieldDescriptorProto::LABEL_OPTIONAL,
+                 FieldDescriptorProto::TYPE_INT32);
+
+    FileDescriptorProto bar_file;
+    bar_file.set_name("bar.proto");
+    bar_file.set_package("bar_package");
+    bar_file.add_dependency("foo.proto");
+    AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2);
+    AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1);
+    AddService(&bar_file, "BarService");
+    AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1,
+                 FieldDescriptorProto::LABEL_OPTIONAL,
+                 FieldDescriptorProto::TYPE_INT32);
+
+    FileDescriptorProto baz_file;
+    baz_file.set_name("baz.proto");
+
+    // Build the descriptors and get the pointers.
+    foo_file_ = pool_.BuildFile(foo_file);
+    ASSERT_TRUE(foo_file_ != NULL);
+
+    bar_file_ = pool_.BuildFile(bar_file);
+    ASSERT_TRUE(bar_file_ != NULL);
+
+    baz_file_ = pool_.BuildFile(baz_file);
+    ASSERT_TRUE(baz_file_ != NULL);
+
+    ASSERT_EQ(1, foo_file_->message_type_count());
+    foo_message_ = foo_file_->message_type(0);
+    ASSERT_EQ(1, foo_file_->enum_type_count());
+    foo_enum_ = foo_file_->enum_type(0);
+    ASSERT_EQ(1, foo_enum_->value_count());
+    foo_enum_value_ = foo_enum_->value(0);
+    ASSERT_EQ(1, foo_file_->service_count());
+    foo_service_ = foo_file_->service(0);
+    ASSERT_EQ(1, foo_file_->extension_count());
+    foo_extension_ = foo_file_->extension(0);
+
+    ASSERT_EQ(1, bar_file_->message_type_count());
+    bar_message_ = bar_file_->message_type(0);
+    ASSERT_EQ(1, bar_file_->enum_type_count());
+    bar_enum_ = bar_file_->enum_type(0);
+    ASSERT_EQ(1, bar_enum_->value_count());
+    bar_enum_value_ = bar_enum_->value(0);
+    ASSERT_EQ(1, bar_file_->service_count());
+    bar_service_ = bar_file_->service(0);
+    ASSERT_EQ(1, bar_file_->extension_count());
+    bar_extension_ = bar_file_->extension(0);
+  }
+
+  DescriptorPool pool_;
+
+  const FileDescriptor* foo_file_;
+  const FileDescriptor* bar_file_;
+  const FileDescriptor* baz_file_;
+
+  const Descriptor*          foo_message_;
+  const EnumDescriptor*      foo_enum_;
+  const EnumValueDescriptor* foo_enum_value_;
+  const ServiceDescriptor*   foo_service_;
+  const FieldDescriptor*     foo_extension_;
+
+  const Descriptor*          bar_message_;
+  const EnumDescriptor*      bar_enum_;
+  const EnumValueDescriptor* bar_enum_value_;
+  const ServiceDescriptor*   bar_service_;
+  const FieldDescriptor*     bar_extension_;
+};
+
+TEST_F(FileDescriptorTest, Name) {
+  EXPECT_EQ("foo.proto", foo_file_->name());
+  EXPECT_EQ("bar.proto", bar_file_->name());
+  EXPECT_EQ("baz.proto", baz_file_->name());
+}
+
+TEST_F(FileDescriptorTest, Package) {
+  EXPECT_EQ("", foo_file_->package());
+  EXPECT_EQ("bar_package", bar_file_->package());
+}
+
+TEST_F(FileDescriptorTest, Dependencies) {
+  EXPECT_EQ(0, foo_file_->dependency_count());
+  EXPECT_EQ(1, bar_file_->dependency_count());
+  EXPECT_EQ(foo_file_, bar_file_->dependency(0));
+}
+
+TEST_F(FileDescriptorTest, FindMessageTypeByName) {
+  EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage"));
+  EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage"));
+
+  EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == NULL);
+  EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == NULL);
+  EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == NULL);
+
+  EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == NULL);
+  EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == NULL);
+}
+
+TEST_F(FileDescriptorTest, FindEnumTypeByName) {
+  EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum"));
+  EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum"));
+
+  EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == NULL);
+  EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == NULL);
+  EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == NULL);
+
+  EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == NULL);
+  EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == NULL);
+}
+
+TEST_F(FileDescriptorTest, FindEnumValueByName) {
+  EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE"));
+  EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE"));
+
+  EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == NULL);
+  EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
+  EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
+
+  EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
+  EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == NULL);
+}
+
+TEST_F(FileDescriptorTest, FindServiceByName) {
+  EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService"));
+  EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService"));
+
+  EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == NULL);
+  EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == NULL);
+  EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == NULL);
+
+  EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == NULL);
+  EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == NULL);
+}
+
+TEST_F(FileDescriptorTest, FindExtensionByName) {
+  EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension"));
+  EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension"));
+
+  EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == NULL);
+  EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == NULL);
+  EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == NULL);
+
+  EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == NULL);
+  EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == NULL);
+}
+
+TEST_F(FileDescriptorTest, FindExtensionByNumber) {
+  EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1));
+  EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1));
+
+  EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == NULL);
+}
+
+// ===================================================================
+
+// Test simple flat messages and fields.
+class DescriptorTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    // Build descriptors for the following definitions:
+    //
+    //   // in "foo.proto"
+    //   message TestForeign {}
+    //   enum TestEnum {}
+    //
+    //   message TestMessage {
+    //     required string      foo = 1;
+    //     optional TestEnum    bar = 6;
+    //     repeated TestForeign baz = 500000000;
+    //     optional group       qux = 15 {}
+    //   }
+    //
+    //   // in "bar.proto"
+    //   package corge.grault;
+    //   message TestMessage2 {
+    //     required string foo = 1;
+    //     required string bar = 2;
+    //     required string quux = 6;
+    //   }
+    //
+    // We cheat and use TestForeign as the type for qux rather than create
+    // an actual nested type.
+    //
+    // Since all primitive types (including string) use the same building
+    // code, there's no need to test each one individually.
+    //
+    // TestMessage2 is primarily here to test FindFieldByName and friends.
+    // All messages created from the same DescriptorPool share the same lookup
+    // table, so we need to insure that they don't interfere.
+
+    FileDescriptorProto foo_file;
+    foo_file.set_name("foo.proto");
+    AddMessage(&foo_file, "TestForeign");
+    AddEmptyEnum(&foo_file, "TestEnum");
+
+    DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
+    AddField(message, "foo", 1,
+             FieldDescriptorProto::LABEL_REQUIRED,
+             FieldDescriptorProto::TYPE_STRING);
+    AddField(message, "bar", 6,
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_ENUM)
+      ->set_type_name("TestEnum");
+    AddField(message, "baz", 500000000,
+             FieldDescriptorProto::LABEL_REPEATED,
+             FieldDescriptorProto::TYPE_MESSAGE)
+      ->set_type_name("TestForeign");
+    AddField(message, "qux", 15,
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_GROUP)
+      ->set_type_name("TestForeign");
+
+    FileDescriptorProto bar_file;
+    bar_file.set_name("bar.proto");
+    bar_file.set_package("corge.grault");
+
+    DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
+    AddField(message2, "foo", 1,
+             FieldDescriptorProto::LABEL_REQUIRED,
+             FieldDescriptorProto::TYPE_STRING);
+    AddField(message2, "bar", 2,
+             FieldDescriptorProto::LABEL_REQUIRED,
+             FieldDescriptorProto::TYPE_STRING);
+    AddField(message2, "quux", 6,
+             FieldDescriptorProto::LABEL_REQUIRED,
+             FieldDescriptorProto::TYPE_STRING);
+
+    // Build the descriptors and get the pointers.
+    foo_file_ = pool_.BuildFile(foo_file);
+    ASSERT_TRUE(foo_file_ != NULL);
+
+    bar_file_ = pool_.BuildFile(bar_file);
+    ASSERT_TRUE(bar_file_ != NULL);
+
+    ASSERT_EQ(1, foo_file_->enum_type_count());
+    enum_ = foo_file_->enum_type(0);
+
+    ASSERT_EQ(2, foo_file_->message_type_count());
+    foreign_ = foo_file_->message_type(0);
+    message_ = foo_file_->message_type(1);
+
+    ASSERT_EQ(4, message_->field_count());
+    foo_ = message_->field(0);
+    bar_ = message_->field(1);
+    baz_ = message_->field(2);
+    qux_ = message_->field(3);
+
+    ASSERT_EQ(1, bar_file_->message_type_count());
+    message2_ = bar_file_->message_type(0);
+
+    ASSERT_EQ(3, message2_->field_count());
+    foo2_  = message2_->field(0);
+    bar2_  = message2_->field(1);
+    quux2_ = message2_->field(2);
+  }
+
+  DescriptorPool pool_;
+
+  const FileDescriptor* foo_file_;
+  const FileDescriptor* bar_file_;
+
+  const Descriptor* message_;
+  const Descriptor* message2_;
+  const Descriptor* foreign_;
+  const EnumDescriptor* enum_;
+
+  const FieldDescriptor* foo_;
+  const FieldDescriptor* bar_;
+  const FieldDescriptor* baz_;
+  const FieldDescriptor* qux_;
+
+  const FieldDescriptor* foo2_;
+  const FieldDescriptor* bar2_;
+  const FieldDescriptor* quux2_;
+};
+
+TEST_F(DescriptorTest, Name) {
+  EXPECT_EQ("TestMessage", message_->name());
+  EXPECT_EQ("TestMessage", message_->full_name());
+  EXPECT_EQ(foo_file_, message_->file());
+
+  EXPECT_EQ("TestMessage2", message2_->name());
+  EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name());
+  EXPECT_EQ(bar_file_, message2_->file());
+}
+
+TEST_F(DescriptorTest, ContainingType) {
+  EXPECT_TRUE(message_->containing_type() == NULL);
+  EXPECT_TRUE(message2_->containing_type() == NULL);
+}
+
+TEST_F(DescriptorTest, FieldsByIndex) {
+  ASSERT_EQ(4, message_->field_count());
+  EXPECT_EQ(foo_, message_->field(0));
+  EXPECT_EQ(bar_, message_->field(1));
+  EXPECT_EQ(baz_, message_->field(2));
+  EXPECT_EQ(qux_, message_->field(3));
+}
+
+TEST_F(DescriptorTest, FindFieldByName) {
+  // All messages in the same DescriptorPool share a single lookup table for
+  // fields.  So, in addition to testing that FindFieldByName finds the fields
+  // of the message, we need to test that it does *not* find the fields of
+  // *other* messages.
+
+  EXPECT_EQ(foo_, message_->FindFieldByName("foo"));
+  EXPECT_EQ(bar_, message_->FindFieldByName("bar"));
+  EXPECT_EQ(baz_, message_->FindFieldByName("baz"));
+  EXPECT_EQ(qux_, message_->FindFieldByName("qux"));
+  EXPECT_TRUE(message_->FindFieldByName("no_such_field") == NULL);
+  EXPECT_TRUE(message_->FindFieldByName("quux") == NULL);
+
+  EXPECT_EQ(foo2_ , message2_->FindFieldByName("foo" ));
+  EXPECT_EQ(bar2_ , message2_->FindFieldByName("bar" ));
+  EXPECT_EQ(quux2_, message2_->FindFieldByName("quux"));
+  EXPECT_TRUE(message2_->FindFieldByName("baz") == NULL);
+  EXPECT_TRUE(message2_->FindFieldByName("qux") == NULL);
+}
+
+TEST_F(DescriptorTest, FindFieldByNumber) {
+  EXPECT_EQ(foo_, message_->FindFieldByNumber(1));
+  EXPECT_EQ(bar_, message_->FindFieldByNumber(6));
+  EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000));
+  EXPECT_EQ(qux_, message_->FindFieldByNumber(15));
+  EXPECT_TRUE(message_->FindFieldByNumber(837592) == NULL);
+  EXPECT_TRUE(message_->FindFieldByNumber(2) == NULL);
+
+  EXPECT_EQ(foo2_ , message2_->FindFieldByNumber(1));
+  EXPECT_EQ(bar2_ , message2_->FindFieldByNumber(2));
+  EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6));
+  EXPECT_TRUE(message2_->FindFieldByNumber(15) == NULL);
+  EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == NULL);
+}
+
+TEST_F(DescriptorTest, FieldName) {
+  EXPECT_EQ("foo", foo_->name());
+  EXPECT_EQ("bar", bar_->name());
+  EXPECT_EQ("baz", baz_->name());
+  EXPECT_EQ("qux", qux_->name());
+}
+
+TEST_F(DescriptorTest, FieldFullName) {
+  EXPECT_EQ("TestMessage.foo", foo_->full_name());
+  EXPECT_EQ("TestMessage.bar", bar_->full_name());
+  EXPECT_EQ("TestMessage.baz", baz_->full_name());
+  EXPECT_EQ("TestMessage.qux", qux_->full_name());
+
+  EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name());
+  EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name());
+  EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name());
+}
+
+TEST_F(DescriptorTest, FieldFile) {
+  EXPECT_EQ(foo_file_, foo_->file());
+  EXPECT_EQ(foo_file_, bar_->file());
+  EXPECT_EQ(foo_file_, baz_->file());
+  EXPECT_EQ(foo_file_, qux_->file());
+
+  EXPECT_EQ(bar_file_, foo2_->file());
+  EXPECT_EQ(bar_file_, bar2_->file());
+  EXPECT_EQ(bar_file_, quux2_->file());
+}
+
+TEST_F(DescriptorTest, FieldIndex) {
+  EXPECT_EQ(0, foo_->index());
+  EXPECT_EQ(1, bar_->index());
+  EXPECT_EQ(2, baz_->index());
+  EXPECT_EQ(3, qux_->index());
+}
+
+TEST_F(DescriptorTest, FieldNumber) {
+  EXPECT_EQ(        1, foo_->number());
+  EXPECT_EQ(        6, bar_->number());
+  EXPECT_EQ(500000000, baz_->number());
+  EXPECT_EQ(       15, qux_->number());
+}
+
+TEST_F(DescriptorTest, FieldType) {
+  EXPECT_EQ(FieldDescriptor::TYPE_STRING , foo_->type());
+  EXPECT_EQ(FieldDescriptor::TYPE_ENUM   , bar_->type());
+  EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type());
+  EXPECT_EQ(FieldDescriptor::TYPE_GROUP  , qux_->type());
+}
+
+TEST_F(DescriptorTest, FieldLabel) {
+  EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label());
+  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label());
+  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label());
+  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label());
+
+  EXPECT_TRUE (foo_->is_required());
+  EXPECT_FALSE(foo_->is_optional());
+  EXPECT_FALSE(foo_->is_repeated());
+
+  EXPECT_FALSE(bar_->is_required());
+  EXPECT_TRUE (bar_->is_optional());
+  EXPECT_FALSE(bar_->is_repeated());
+
+  EXPECT_FALSE(baz_->is_required());
+  EXPECT_FALSE(baz_->is_optional());
+  EXPECT_TRUE (baz_->is_repeated());
+}
+
+TEST_F(DescriptorTest, FieldHasDefault) {
+  EXPECT_FALSE(foo_->has_default_value());
+  EXPECT_FALSE(bar_->has_default_value());
+  EXPECT_FALSE(baz_->has_default_value());
+  EXPECT_FALSE(qux_->has_default_value());
+}
+
+TEST_F(DescriptorTest, FieldContainingType) {
+  EXPECT_EQ(message_, foo_->containing_type());
+  EXPECT_EQ(message_, bar_->containing_type());
+  EXPECT_EQ(message_, baz_->containing_type());
+  EXPECT_EQ(message_, qux_->containing_type());
+
+  EXPECT_EQ(message2_, foo2_ ->containing_type());
+  EXPECT_EQ(message2_, bar2_ ->containing_type());
+  EXPECT_EQ(message2_, quux2_->containing_type());
+}
+
+TEST_F(DescriptorTest, FieldMessageType) {
+  EXPECT_TRUE(foo_->message_type() == NULL);
+  EXPECT_TRUE(bar_->message_type() == NULL);
+
+  EXPECT_EQ(foreign_, baz_->message_type());
+  EXPECT_EQ(foreign_, qux_->message_type());
+}
+
+TEST_F(DescriptorTest, FieldEnumType) {
+  EXPECT_TRUE(foo_->enum_type() == NULL);
+  EXPECT_TRUE(baz_->enum_type() == NULL);
+  EXPECT_TRUE(qux_->enum_type() == NULL);
+
+  EXPECT_EQ(enum_, bar_->enum_type());
+}
+
+// ===================================================================
+
+// Test enum descriptors.
+class EnumDescriptorTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    // Build descriptors for the following definitions:
+    //
+    //   // in "foo.proto"
+    //   enum TestEnum {
+    //     FOO = 1;
+    //     BAR = 2;
+    //   }
+    //
+    //   // in "bar.proto"
+    //   package corge.grault;
+    //   enum TestEnum2 {
+    //     FOO = 1;
+    //     BAZ = 3;
+    //   }
+    //
+    // TestEnum2 is primarily here to test FindValueByName and friends.
+    // All enums created from the same DescriptorPool share the same lookup
+    // table, so we need to insure that they don't interfere.
+
+    // TestEnum
+    FileDescriptorProto foo_file;
+    foo_file.set_name("foo.proto");
+
+    EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum");
+    AddEnumValue(enum_proto, "FOO", 1);
+    AddEnumValue(enum_proto, "BAR", 2);
+
+    // TestEnum2
+    FileDescriptorProto bar_file;
+    bar_file.set_name("bar.proto");
+    bar_file.set_package("corge.grault");
+
+    EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2");
+    AddEnumValue(enum2_proto, "FOO", 1);
+    AddEnumValue(enum2_proto, "BAZ", 3);
+
+    // Build the descriptors and get the pointers.
+    foo_file_ = pool_.BuildFile(foo_file);
+    ASSERT_TRUE(foo_file_ != NULL);
+
+    bar_file_ = pool_.BuildFile(bar_file);
+    ASSERT_TRUE(bar_file_ != NULL);
+
+    ASSERT_EQ(1, foo_file_->enum_type_count());
+    enum_ = foo_file_->enum_type(0);
+
+    ASSERT_EQ(2, enum_->value_count());
+    foo_ = enum_->value(0);
+    bar_ = enum_->value(1);
+
+    ASSERT_EQ(1, bar_file_->enum_type_count());
+    enum2_ = bar_file_->enum_type(0);
+
+    ASSERT_EQ(2, enum2_->value_count());
+    foo2_ = enum2_->value(0);
+    baz2_ = enum2_->value(1);
+  }
+
+  DescriptorPool pool_;
+
+  const FileDescriptor* foo_file_;
+  const FileDescriptor* bar_file_;
+
+  const EnumDescriptor* enum_;
+  const EnumDescriptor* enum2_;
+
+  const EnumValueDescriptor* foo_;
+  const EnumValueDescriptor* bar_;
+
+  const EnumValueDescriptor* foo2_;
+  const EnumValueDescriptor* baz2_;
+};
+
+TEST_F(EnumDescriptorTest, Name) {
+  EXPECT_EQ("TestEnum", enum_->name());
+  EXPECT_EQ("TestEnum", enum_->full_name());
+  EXPECT_EQ(foo_file_, enum_->file());
+
+  EXPECT_EQ("TestEnum2", enum2_->name());
+  EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name());
+  EXPECT_EQ(bar_file_, enum2_->file());
+}
+
+TEST_F(EnumDescriptorTest, ContainingType) {
+  EXPECT_TRUE(enum_->containing_type() == NULL);
+  EXPECT_TRUE(enum2_->containing_type() == NULL);
+}
+
+TEST_F(EnumDescriptorTest, ValuesByIndex) {
+  ASSERT_EQ(2, enum_->value_count());
+  EXPECT_EQ(foo_, enum_->value(0));
+  EXPECT_EQ(bar_, enum_->value(1));
+}
+
+TEST_F(EnumDescriptorTest, FindValueByName) {
+  EXPECT_EQ(foo_ , enum_ ->FindValueByName("FOO"));
+  EXPECT_EQ(bar_ , enum_ ->FindValueByName("BAR"));
+  EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO"));
+  EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ"));
+
+  EXPECT_TRUE(enum_ ->FindValueByName("NO_SUCH_VALUE") == NULL);
+  EXPECT_TRUE(enum_ ->FindValueByName("BAZ"          ) == NULL);
+  EXPECT_TRUE(enum2_->FindValueByName("BAR"          ) == NULL);
+}
+
+TEST_F(EnumDescriptorTest, FindValueByNumber) {
+  EXPECT_EQ(foo_ , enum_ ->FindValueByNumber(1));
+  EXPECT_EQ(bar_ , enum_ ->FindValueByNumber(2));
+  EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1));
+  EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3));
+
+  EXPECT_TRUE(enum_ ->FindValueByNumber(416) == NULL);
+  EXPECT_TRUE(enum_ ->FindValueByNumber(3) == NULL);
+  EXPECT_TRUE(enum2_->FindValueByNumber(2) == NULL);
+}
+
+TEST_F(EnumDescriptorTest, ValueName) {
+  EXPECT_EQ("FOO", foo_->name());
+  EXPECT_EQ("BAR", bar_->name());
+}
+
+TEST_F(EnumDescriptorTest, ValueFullName) {
+  EXPECT_EQ("FOO", foo_->full_name());
+  EXPECT_EQ("BAR", bar_->full_name());
+  EXPECT_EQ("corge.grault.FOO", foo2_->full_name());
+  EXPECT_EQ("corge.grault.BAZ", baz2_->full_name());
+}
+
+TEST_F(EnumDescriptorTest, ValueIndex) {
+  EXPECT_EQ(0, foo_->index());
+  EXPECT_EQ(1, bar_->index());
+}
+
+TEST_F(EnumDescriptorTest, ValueNumber) {
+  EXPECT_EQ(1, foo_->number());
+  EXPECT_EQ(2, bar_->number());
+}
+
+TEST_F(EnumDescriptorTest, ValueType) {
+  EXPECT_EQ(enum_ , foo_ ->type());
+  EXPECT_EQ(enum_ , bar_ ->type());
+  EXPECT_EQ(enum2_, foo2_->type());
+  EXPECT_EQ(enum2_, baz2_->type());
+}
+
+// ===================================================================
+
+// Test service descriptors.
+class ServiceDescriptorTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    // Build descriptors for the following messages and service:
+    //    // in "foo.proto"
+    //    message FooRequest  {}
+    //    message FooResponse {}
+    //    message BarRequest  {}
+    //    message BarResponse {}
+    //    message BazRequest  {}
+    //    message BazResponse {}
+    //
+    //    service TestService {
+    //      rpc Foo(FooRequest) returns (FooResponse);
+    //      rpc Bar(BarRequest) returns (BarResponse);
+    //    }
+    //
+    //    // in "bar.proto"
+    //    package corge.grault
+    //    service TestService2 {
+    //      rpc Foo(FooRequest) returns (FooResponse);
+    //      rpc Baz(BazRequest) returns (BazResponse);
+    //    }
+
+    FileDescriptorProto foo_file;
+    foo_file.set_name("foo.proto");
+
+    AddMessage(&foo_file, "FooRequest");
+    AddMessage(&foo_file, "FooResponse");
+    AddMessage(&foo_file, "BarRequest");
+    AddMessage(&foo_file, "BarResponse");
+    AddMessage(&foo_file, "BazRequest");
+    AddMessage(&foo_file, "BazResponse");
+
+    ServiceDescriptorProto* service = AddService(&foo_file, "TestService");
+    AddMethod(service, "Foo", "FooRequest", "FooResponse");
+    AddMethod(service, "Bar", "BarRequest", "BarResponse");
+
+    FileDescriptorProto bar_file;
+    bar_file.set_name("bar.proto");
+    bar_file.set_package("corge.grault");
+    bar_file.add_dependency("foo.proto");
+
+    ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2");
+    AddMethod(service2, "Foo", "FooRequest", "FooResponse");
+    AddMethod(service2, "Baz", "BazRequest", "BazResponse");
+
+    // Build the descriptors and get the pointers.
+    foo_file_ = pool_.BuildFile(foo_file);
+    ASSERT_TRUE(foo_file_ != NULL);
+
+    bar_file_ = pool_.BuildFile(bar_file);
+    ASSERT_TRUE(bar_file_ != NULL);
+
+    ASSERT_EQ(6, foo_file_->message_type_count());
+    foo_request_  = foo_file_->message_type(0);
+    foo_response_ = foo_file_->message_type(1);
+    bar_request_  = foo_file_->message_type(2);
+    bar_response_ = foo_file_->message_type(3);
+    baz_request_  = foo_file_->message_type(4);
+    baz_response_ = foo_file_->message_type(5);
+
+    ASSERT_EQ(1, foo_file_->service_count());
+    service_ = foo_file_->service(0);
+
+    ASSERT_EQ(2, service_->method_count());
+    foo_ = service_->method(0);
+    bar_ = service_->method(1);
+
+    ASSERT_EQ(1, bar_file_->service_count());
+    service2_ = bar_file_->service(0);
+
+    ASSERT_EQ(2, service2_->method_count());
+    foo2_ = service2_->method(0);
+    baz2_ = service2_->method(1);
+  }
+
+  DescriptorPool pool_;
+
+  const FileDescriptor* foo_file_;
+  const FileDescriptor* bar_file_;
+
+  const Descriptor* foo_request_;
+  const Descriptor* foo_response_;
+  const Descriptor* bar_request_;
+  const Descriptor* bar_response_;
+  const Descriptor* baz_request_;
+  const Descriptor* baz_response_;
+
+  const ServiceDescriptor* service_;
+  const ServiceDescriptor* service2_;
+
+  const MethodDescriptor* foo_;
+  const MethodDescriptor* bar_;
+
+  const MethodDescriptor* foo2_;
+  const MethodDescriptor* baz2_;
+};
+
+TEST_F(ServiceDescriptorTest, Name) {
+  EXPECT_EQ("TestService", service_->name());
+  EXPECT_EQ("TestService", service_->full_name());
+  EXPECT_EQ(foo_file_, service_->file());
+
+  EXPECT_EQ("TestService2", service2_->name());
+  EXPECT_EQ("corge.grault.TestService2", service2_->full_name());
+  EXPECT_EQ(bar_file_, service2_->file());
+}
+
+TEST_F(ServiceDescriptorTest, MethodsByIndex) {
+  ASSERT_EQ(2, service_->method_count());
+  EXPECT_EQ(foo_, service_->method(0));
+  EXPECT_EQ(bar_, service_->method(1));
+}
+
+TEST_F(ServiceDescriptorTest, FindMethodByName) {
+  EXPECT_EQ(foo_ , service_ ->FindMethodByName("Foo"));
+  EXPECT_EQ(bar_ , service_ ->FindMethodByName("Bar"));
+  EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo"));
+  EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz"));
+
+  EXPECT_TRUE(service_ ->FindMethodByName("NoSuchMethod") == NULL);
+  EXPECT_TRUE(service_ ->FindMethodByName("Baz"         ) == NULL);
+  EXPECT_TRUE(service2_->FindMethodByName("Bar"         ) == NULL);
+}
+
+TEST_F(ServiceDescriptorTest, MethodName) {
+  EXPECT_EQ("Foo", foo_->name());
+  EXPECT_EQ("Bar", bar_->name());
+}
+
+TEST_F(ServiceDescriptorTest, MethodFullName) {
+  EXPECT_EQ("TestService.Foo", foo_->full_name());
+  EXPECT_EQ("TestService.Bar", bar_->full_name());
+  EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name());
+  EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name());
+}
+
+TEST_F(ServiceDescriptorTest, MethodIndex) {
+  EXPECT_EQ(0, foo_->index());
+  EXPECT_EQ(1, bar_->index());
+}
+
+TEST_F(ServiceDescriptorTest, MethodParent) {
+  EXPECT_EQ(service_, foo_->service());
+  EXPECT_EQ(service_, bar_->service());
+}
+
+TEST_F(ServiceDescriptorTest, MethodInputType) {
+  EXPECT_EQ(foo_request_, foo_->input_type());
+  EXPECT_EQ(bar_request_, bar_->input_type());
+}
+
+TEST_F(ServiceDescriptorTest, MethodOutputType) {
+  EXPECT_EQ(foo_response_, foo_->output_type());
+  EXPECT_EQ(bar_response_, bar_->output_type());
+}
+
+// ===================================================================
+
+// Test nested types.
+class NestedDescriptorTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    // Build descriptors for the following definitions:
+    //
+    //   // in "foo.proto"
+    //   message TestMessage {
+    //     message Foo {}
+    //     message Bar {}
+    //     enum Baz { A = 1; }
+    //     enum Qux { B = 1; }
+    //   }
+    //
+    //   // in "bar.proto"
+    //   package corge.grault;
+    //   message TestMessage2 {
+    //     message Foo {}
+    //     message Baz {}
+    //     enum Qux  { A = 1; }
+    //     enum Quux { C = 1; }
+    //   }
+    //
+    // TestMessage2 is primarily here to test FindNestedTypeByName and friends.
+    // All messages created from the same DescriptorPool share the same lookup
+    // table, so we need to insure that they don't interfere.
+    //
+    // We add enum values to the enums in order to test searching for enum
+    // values across a message's scope.
+
+    FileDescriptorProto foo_file;
+    foo_file.set_name("foo.proto");
+
+    DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
+    AddNestedMessage(message, "Foo");
+    AddNestedMessage(message, "Bar");
+    EnumDescriptorProto* baz = AddNestedEnum(message, "Baz");
+    AddEnumValue(baz, "A", 1);
+    EnumDescriptorProto* qux = AddNestedEnum(message, "Qux");
+    AddEnumValue(qux, "B", 1);
+
+    FileDescriptorProto bar_file;
+    bar_file.set_name("bar.proto");
+    bar_file.set_package("corge.grault");
+
+    DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
+    AddNestedMessage(message2, "Foo");
+    AddNestedMessage(message2, "Baz");
+    EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux");
+    AddEnumValue(qux2, "A", 1);
+    EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux");
+    AddEnumValue(quux2, "C", 1);
+
+    // Build the descriptors and get the pointers.
+    foo_file_ = pool_.BuildFile(foo_file);
+    ASSERT_TRUE(foo_file_ != NULL);
+
+    bar_file_ = pool_.BuildFile(bar_file);
+    ASSERT_TRUE(bar_file_ != NULL);
+
+    ASSERT_EQ(1, foo_file_->message_type_count());
+    message_ = foo_file_->message_type(0);
+
+    ASSERT_EQ(2, message_->nested_type_count());
+    foo_ = message_->nested_type(0);
+    bar_ = message_->nested_type(1);
+
+    ASSERT_EQ(2, message_->enum_type_count());
+    baz_ = message_->enum_type(0);
+    qux_ = message_->enum_type(1);
+
+    ASSERT_EQ(1, baz_->value_count());
+    a_ = baz_->value(0);
+    ASSERT_EQ(1, qux_->value_count());
+    b_ = qux_->value(0);
+
+    ASSERT_EQ(1, bar_file_->message_type_count());
+    message2_ = bar_file_->message_type(0);
+
+    ASSERT_EQ(2, message2_->nested_type_count());
+    foo2_ = message2_->nested_type(0);
+    baz2_ = message2_->nested_type(1);
+
+    ASSERT_EQ(2, message2_->enum_type_count());
+    qux2_ = message2_->enum_type(0);
+    quux2_ = message2_->enum_type(1);
+
+    ASSERT_EQ(1, qux2_->value_count());
+    a2_ = qux2_->value(0);
+    ASSERT_EQ(1, quux2_->value_count());
+    c2_ = quux2_->value(0);
+  }
+
+  DescriptorPool pool_;
+
+  const FileDescriptor* foo_file_;
+  const FileDescriptor* bar_file_;
+
+  const Descriptor* message_;
+  const Descriptor* message2_;
+
+  const Descriptor* foo_;
+  const Descriptor* bar_;
+  const EnumDescriptor* baz_;
+  const EnumDescriptor* qux_;
+  const EnumValueDescriptor* a_;
+  const EnumValueDescriptor* b_;
+
+  const Descriptor* foo2_;
+  const Descriptor* baz2_;
+  const EnumDescriptor* qux2_;
+  const EnumDescriptor* quux2_;
+  const EnumValueDescriptor* a2_;
+  const EnumValueDescriptor* c2_;
+};
+
+TEST_F(NestedDescriptorTest, MessageName) {
+  EXPECT_EQ("Foo", foo_ ->name());
+  EXPECT_EQ("Bar", bar_ ->name());
+  EXPECT_EQ("Foo", foo2_->name());
+  EXPECT_EQ("Baz", baz2_->name());
+
+  EXPECT_EQ("TestMessage.Foo", foo_->full_name());
+  EXPECT_EQ("TestMessage.Bar", bar_->full_name());
+  EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name());
+  EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name());
+}
+
+TEST_F(NestedDescriptorTest, MessageContainingType) {
+  EXPECT_EQ(message_ , foo_ ->containing_type());
+  EXPECT_EQ(message_ , bar_ ->containing_type());
+  EXPECT_EQ(message2_, foo2_->containing_type());
+  EXPECT_EQ(message2_, baz2_->containing_type());
+}
+
+TEST_F(NestedDescriptorTest, NestedMessagesByIndex) {
+  ASSERT_EQ(2, message_->nested_type_count());
+  EXPECT_EQ(foo_, message_->nested_type(0));
+  EXPECT_EQ(bar_, message_->nested_type(1));
+}
+
+TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) {
+  EXPECT_TRUE(message_->FindFieldByName("Foo") == NULL);
+  EXPECT_TRUE(message_->FindFieldByName("Qux") == NULL);
+  EXPECT_TRUE(message_->FindExtensionByName("Foo") == NULL);
+  EXPECT_TRUE(message_->FindExtensionByName("Qux") == NULL);
+}
+
+TEST_F(NestedDescriptorTest, FindNestedTypeByName) {
+  EXPECT_EQ(foo_ , message_ ->FindNestedTypeByName("Foo"));
+  EXPECT_EQ(bar_ , message_ ->FindNestedTypeByName("Bar"));
+  EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo"));
+  EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz"));
+
+  EXPECT_TRUE(message_ ->FindNestedTypeByName("NoSuchType") == NULL);
+  EXPECT_TRUE(message_ ->FindNestedTypeByName("Baz"       ) == NULL);
+  EXPECT_TRUE(message2_->FindNestedTypeByName("Bar"       ) == NULL);
+
+  EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == NULL);
+}
+
+TEST_F(NestedDescriptorTest, EnumName) {
+  EXPECT_EQ("Baz" , baz_ ->name());
+  EXPECT_EQ("Qux" , qux_ ->name());
+  EXPECT_EQ("Qux" , qux2_->name());
+  EXPECT_EQ("Quux", quux2_->name());
+
+  EXPECT_EQ("TestMessage.Baz", baz_->full_name());
+  EXPECT_EQ("TestMessage.Qux", qux_->full_name());
+  EXPECT_EQ("corge.grault.TestMessage2.Qux" , qux2_ ->full_name());
+  EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name());
+}
+
+TEST_F(NestedDescriptorTest, EnumContainingType) {
+  EXPECT_EQ(message_ , baz_  ->containing_type());
+  EXPECT_EQ(message_ , qux_  ->containing_type());
+  EXPECT_EQ(message2_, qux2_ ->containing_type());
+  EXPECT_EQ(message2_, quux2_->containing_type());
+}
+
+TEST_F(NestedDescriptorTest, NestedEnumsByIndex) {
+  ASSERT_EQ(2, message_->nested_type_count());
+  EXPECT_EQ(foo_, message_->nested_type(0));
+  EXPECT_EQ(bar_, message_->nested_type(1));
+}
+
+TEST_F(NestedDescriptorTest, FindEnumTypeByName) {
+  EXPECT_EQ(baz_  , message_ ->FindEnumTypeByName("Baz" ));
+  EXPECT_EQ(qux_  , message_ ->FindEnumTypeByName("Qux" ));
+  EXPECT_EQ(qux2_ , message2_->FindEnumTypeByName("Qux" ));
+  EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux"));
+
+  EXPECT_TRUE(message_ ->FindEnumTypeByName("NoSuchType") == NULL);
+  EXPECT_TRUE(message_ ->FindEnumTypeByName("Quux"      ) == NULL);
+  EXPECT_TRUE(message2_->FindEnumTypeByName("Baz"       ) == NULL);
+
+  EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == NULL);
+}
+
+TEST_F(NestedDescriptorTest, FindEnumValueByName) {
+  EXPECT_EQ(a_ , message_ ->FindEnumValueByName("A"));
+  EXPECT_EQ(b_ , message_ ->FindEnumValueByName("B"));
+  EXPECT_EQ(a2_, message2_->FindEnumValueByName("A"));
+  EXPECT_EQ(c2_, message2_->FindEnumValueByName("C"));
+
+  EXPECT_TRUE(message_ ->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
+  EXPECT_TRUE(message_ ->FindEnumValueByName("C"            ) == NULL);
+  EXPECT_TRUE(message2_->FindEnumValueByName("B"            ) == NULL);
+
+  EXPECT_TRUE(message_->FindEnumValueByName("Foo") == NULL);
+}
+
+// ===================================================================
+
+// Test extensions.
+class ExtensionDescriptorTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    // Build descriptors for the following definitions:
+    //
+    //   enum Baz {}
+    //   message Qux {}
+    //
+    //   message Foo {
+    //     extensions 10 to 19;
+    //     extensions 30 to 39;
+    //   }
+    //   extends Foo with optional int32 foo_int32 = 10;
+    //   extends Foo with repeated TestEnum foo_enum = 19;
+    //   message Bar {
+    //     extends Foo with optional Qux foo_message = 30;
+    //     // (using Qux as the group type)
+    //     extends Foo with repeated group foo_group = 39;
+    //   }
+
+    FileDescriptorProto foo_file;
+    foo_file.set_name("foo.proto");
+
+    AddEmptyEnum(&foo_file, "Baz");
+    AddMessage(&foo_file, "Qux");
+
+    DescriptorProto* foo = AddMessage(&foo_file, "Foo");
+    AddExtensionRange(foo, 10, 20);
+    AddExtensionRange(foo, 30, 40);
+
+    AddExtension(&foo_file, "Foo", "foo_int32", 10,
+                 FieldDescriptorProto::LABEL_OPTIONAL,
+                 FieldDescriptorProto::TYPE_INT32);
+    AddExtension(&foo_file, "Foo", "foo_enum", 19,
+                 FieldDescriptorProto::LABEL_REPEATED,
+                 FieldDescriptorProto::TYPE_ENUM)
+      ->set_type_name("Baz");
+
+    DescriptorProto* bar = AddMessage(&foo_file, "Bar");
+    AddNestedExtension(bar, "Foo", "foo_message", 30,
+                       FieldDescriptorProto::LABEL_OPTIONAL,
+                       FieldDescriptorProto::TYPE_MESSAGE)
+      ->set_type_name("Qux");
+    AddNestedExtension(bar, "Foo", "foo_group", 39,
+                       FieldDescriptorProto::LABEL_REPEATED,
+                       FieldDescriptorProto::TYPE_GROUP)
+      ->set_type_name("Qux");
+
+    // Build the descriptors and get the pointers.
+    foo_file_ = pool_.BuildFile(foo_file);
+    ASSERT_TRUE(foo_file_ != NULL);
+
+    ASSERT_EQ(1, foo_file_->enum_type_count());
+    baz_ = foo_file_->enum_type(0);
+
+    ASSERT_EQ(3, foo_file_->message_type_count());
+    qux_ = foo_file_->message_type(0);
+    foo_ = foo_file_->message_type(1);
+    bar_ = foo_file_->message_type(2);
+  }
+
+  DescriptorPool pool_;
+
+  const FileDescriptor* foo_file_;
+
+  const Descriptor* foo_;
+  const Descriptor* bar_;
+  const EnumDescriptor* baz_;
+  const Descriptor* qux_;
+};
+
+TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
+  EXPECT_EQ(0, bar_->extension_range_count());
+  ASSERT_EQ(2, foo_->extension_range_count());
+
+  EXPECT_EQ(10, foo_->extension_range(0)->start);
+  EXPECT_EQ(30, foo_->extension_range(1)->start);
+
+  EXPECT_EQ(20, foo_->extension_range(0)->end);
+  EXPECT_EQ(40, foo_->extension_range(1)->end);
+};
+
+TEST_F(ExtensionDescriptorTest, Extensions) {
+  EXPECT_EQ(0, foo_->extension_count());
+  ASSERT_EQ(2, foo_file_->extension_count());
+  ASSERT_EQ(2, bar_->extension_count());
+
+  EXPECT_TRUE(foo_file_->extension(0)->is_extension());
+  EXPECT_TRUE(foo_file_->extension(1)->is_extension());
+  EXPECT_TRUE(bar_->extension(0)->is_extension());
+  EXPECT_TRUE(bar_->extension(1)->is_extension());
+
+  EXPECT_EQ("foo_int32"  , foo_file_->extension(0)->name());
+  EXPECT_EQ("foo_enum"   , foo_file_->extension(1)->name());
+  EXPECT_EQ("foo_message", bar_->extension(0)->name());
+  EXPECT_EQ("foo_group"  , bar_->extension(1)->name());
+
+  EXPECT_EQ(10, foo_file_->extension(0)->number());
+  EXPECT_EQ(19, foo_file_->extension(1)->number());
+  EXPECT_EQ(30, bar_->extension(0)->number());
+  EXPECT_EQ(39, bar_->extension(1)->number());
+
+  EXPECT_EQ(FieldDescriptor::TYPE_INT32  , foo_file_->extension(0)->type());
+  EXPECT_EQ(FieldDescriptor::TYPE_ENUM   , foo_file_->extension(1)->type());
+  EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type());
+  EXPECT_EQ(FieldDescriptor::TYPE_GROUP  , bar_->extension(1)->type());
+
+  EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type());
+  EXPECT_EQ(qux_, bar_->extension(0)->message_type());
+  EXPECT_EQ(qux_, bar_->extension(1)->message_type());
+
+  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label());
+  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label());
+  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label());
+  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label());
+
+  EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type());
+  EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type());
+  EXPECT_EQ(foo_, bar_->extension(0)->containing_type());
+  EXPECT_EQ(foo_, bar_->extension(1)->containing_type());
+
+  EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == NULL);
+  EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == NULL);
+  EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
+  EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
+};
+
+TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
+  EXPECT_FALSE(foo_->IsExtensionNumber( 9));
+  EXPECT_TRUE (foo_->IsExtensionNumber(10));
+  EXPECT_TRUE (foo_->IsExtensionNumber(19));
+  EXPECT_FALSE(foo_->IsExtensionNumber(20));
+  EXPECT_FALSE(foo_->IsExtensionNumber(29));
+  EXPECT_TRUE (foo_->IsExtensionNumber(30));
+  EXPECT_TRUE (foo_->IsExtensionNumber(39));
+  EXPECT_FALSE(foo_->IsExtensionNumber(40));
+}
+
+TEST_F(ExtensionDescriptorTest, FindExtensionByName) {
+  // Note that FileDescriptor::FindExtensionByName() is tested by
+  // FileDescriptorTest.
+  ASSERT_EQ(2, bar_->extension_count());
+
+  EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message"));
+  EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group"  ));
+
+  EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL);
+  EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL);
+  EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL);
+}
+
+// ===================================================================
+
+class MiscTest : public testing::Test {
+ protected:
+  // Function which makes a field of the given type just to find out what its
+  // cpp_type is.
+  FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
+    FileDescriptorProto file_proto;
+    file_proto.set_name("foo.proto");
+    AddEmptyEnum(&file_proto, "DummyEnum");
+
+    DescriptorProto* message = AddMessage(&file_proto, "TestMessage");
+    FieldDescriptorProto* field =
+      AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
+               static_cast<FieldDescriptorProto::Type>(type));
+
+    if (type == FieldDescriptor::TYPE_MESSAGE ||
+        type == FieldDescriptor::TYPE_GROUP) {
+      field->set_type_name("TestMessage");
+    } else if (type == FieldDescriptor::TYPE_ENUM) {
+      field->set_type_name("DummyEnum");
+    }
+
+    // Build the descriptors and get the pointers.
+    DescriptorPool pool;
+    const FileDescriptor* file = pool.BuildFile(file_proto);
+
+    if (file != NULL &&
+        file->message_type_count() == 1 &&
+        file->message_type(0)->field_count() == 1) {
+      return file->message_type(0)->field(0)->cpp_type();
+    } else {
+      return static_cast<FieldDescriptor::CppType>(0);
+    }
+  }
+};
+
+TEST_F(MiscTest, CppTypes) {
+  // Test that CPP types are assigned correctly.
+
+  typedef FieldDescriptor FD;  // avoid ugly line wrapping
+
+  EXPECT_EQ(FD::CPPTYPE_DOUBLE , GetCppTypeForFieldType(FD::TYPE_DOUBLE  ));
+  EXPECT_EQ(FD::CPPTYPE_FLOAT  , GetCppTypeForFieldType(FD::TYPE_FLOAT   ));
+  EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_INT64   ));
+  EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_UINT64  ));
+  EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_INT32   ));
+  EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_FIXED64 ));
+  EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_FIXED32 ));
+  EXPECT_EQ(FD::CPPTYPE_BOOL   , GetCppTypeForFieldType(FD::TYPE_BOOL    ));
+  EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_STRING  ));
+  EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP   ));
+  EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE ));
+  EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_BYTES   ));
+  EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_UINT32  ));
+  EXPECT_EQ(FD::CPPTYPE_ENUM   , GetCppTypeForFieldType(FD::TYPE_ENUM    ));
+  EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_SFIXED32));
+  EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_SFIXED64));
+  EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_SINT32  ));
+  EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_SINT64  ));
+}
+
+TEST_F(MiscTest, DefaultValues) {
+  // Test that setting default values works.
+  FileDescriptorProto file_proto;
+  file_proto.set_name("foo.proto");
+
+  EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum");
+  AddEnumValue(enum_type_proto, "A", 1);
+  AddEnumValue(enum_type_proto, "B", 2);
+
+  DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
+
+  typedef FieldDescriptorProto FD;  // avoid ugly line wrapping
+  const FD::Label label = FD::LABEL_OPTIONAL;
+
+  // Create fields of every CPP type with default values.
+  AddField(message_proto, "int32" , 1, label, FD::TYPE_INT32 )
+    ->set_default_value("-1");
+  AddField(message_proto, "int64" , 2, label, FD::TYPE_INT64 )
+    ->set_default_value("-1000000000000");
+  AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32)
+    ->set_default_value("42");
+  AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64)
+    ->set_default_value("2000000000000");
+  AddField(message_proto, "float" , 5, label, FD::TYPE_FLOAT )
+    ->set_default_value("4.5");
+  AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE)
+    ->set_default_value("10e100");
+  AddField(message_proto, "bool"  , 7, label, FD::TYPE_BOOL  )
+    ->set_default_value("true");
+  AddField(message_proto, "string", 8, label, FD::TYPE_STRING)
+    ->set_default_value("hello");
+  AddField(message_proto, "data"  , 9, label, FD::TYPE_BYTES )
+    ->set_default_value("\\001\\002\\003");
+
+  FieldDescriptorProto* enum_field =
+    AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM);
+  enum_field->set_type_name("DummyEnum");
+  enum_field->set_default_value("B");
+
+  // Strings are allowed to have empty defaults.  (At one point, due to
+  // a bug, empty defaults for strings were rejected.  Oops.)
+  AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING)
+    ->set_default_value("");
+
+  // Add a second set of fields with implicit defalut values.
+  AddField(message_proto, "implicit_int32" , 21, label, FD::TYPE_INT32 );
+  AddField(message_proto, "implicit_int64" , 22, label, FD::TYPE_INT64 );
+  AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32);
+  AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64);
+  AddField(message_proto, "implicit_float" , 25, label, FD::TYPE_FLOAT );
+  AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE);
+  AddField(message_proto, "implicit_bool"  , 27, label, FD::TYPE_BOOL  );
+  AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING);
+  AddField(message_proto, "implicit_data"  , 29, label, FD::TYPE_BYTES );
+  AddField(message_proto, "implicit_enum"  , 30, label, FD::TYPE_ENUM)
+    ->set_type_name("DummyEnum");
+
+  // Build it.
+  DescriptorPool pool;
+  const FileDescriptor* file = pool.BuildFile(file_proto);
+  ASSERT_TRUE(file != NULL);
+
+  ASSERT_EQ(1, file->enum_type_count());
+  const EnumDescriptor* enum_type = file->enum_type(0);
+  ASSERT_EQ(2, enum_type->value_count());
+  const EnumValueDescriptor* enum_value_a = enum_type->value(0);
+  const EnumValueDescriptor* enum_value_b = enum_type->value(1);
+
+  ASSERT_EQ(1, file->message_type_count());
+  const Descriptor* message = file->message_type(0);
+
+  ASSERT_EQ(21, message->field_count());
+
+  // Check the default values.
+  ASSERT_TRUE(message->field(0)->has_default_value());
+  ASSERT_TRUE(message->field(1)->has_default_value());
+  ASSERT_TRUE(message->field(2)->has_default_value());
+  ASSERT_TRUE(message->field(3)->has_default_value());
+  ASSERT_TRUE(message->field(4)->has_default_value());
+  ASSERT_TRUE(message->field(5)->has_default_value());
+  ASSERT_TRUE(message->field(6)->has_default_value());
+  ASSERT_TRUE(message->field(7)->has_default_value());
+  ASSERT_TRUE(message->field(8)->has_default_value());
+  ASSERT_TRUE(message->field(9)->has_default_value());
+  ASSERT_TRUE(message->field(10)->has_default_value());
+
+  EXPECT_EQ(-1              , message->field(0)->default_value_int32 ());
+  EXPECT_EQ(-GOOGLE_ULONGLONG(1000000000000),
+            message->field(1)->default_value_int64 ());
+  EXPECT_EQ(42              , message->field(2)->default_value_uint32());
+  EXPECT_EQ(GOOGLE_ULONGLONG(2000000000000),
+            message->field(3)->default_value_uint64());
+  EXPECT_EQ(4.5             , message->field(4)->default_value_float ());
+  EXPECT_EQ(10e100          , message->field(5)->default_value_double());
+  EXPECT_EQ(true            , message->field(6)->default_value_bool  ());
+  EXPECT_EQ("hello"         , message->field(7)->default_value_string());
+  EXPECT_EQ("\001\002\003"  , message->field(8)->default_value_string());
+  EXPECT_EQ(enum_value_b    , message->field(9)->default_value_enum  ());
+  EXPECT_EQ(""              , message->field(10)->default_value_string());
+
+  ASSERT_FALSE(message->field(11)->has_default_value());
+  ASSERT_FALSE(message->field(12)->has_default_value());
+  ASSERT_FALSE(message->field(13)->has_default_value());
+  ASSERT_FALSE(message->field(14)->has_default_value());
+  ASSERT_FALSE(message->field(15)->has_default_value());
+  ASSERT_FALSE(message->field(16)->has_default_value());
+  ASSERT_FALSE(message->field(17)->has_default_value());
+  ASSERT_FALSE(message->field(18)->has_default_value());
+  ASSERT_FALSE(message->field(19)->has_default_value());
+  ASSERT_FALSE(message->field(20)->has_default_value());
+
+  EXPECT_EQ(0    , message->field(11)->default_value_int32 ());
+  EXPECT_EQ(0    , message->field(12)->default_value_int64 ());
+  EXPECT_EQ(0    , message->field(13)->default_value_uint32());
+  EXPECT_EQ(0    , message->field(14)->default_value_uint64());
+  EXPECT_EQ(0.0f , message->field(15)->default_value_float ());
+  EXPECT_EQ(0.0  , message->field(16)->default_value_double());
+  EXPECT_EQ(false, message->field(17)->default_value_bool  ());
+  EXPECT_EQ(""   , message->field(18)->default_value_string());
+  EXPECT_EQ(""   , message->field(19)->default_value_string());
+  EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
+}
+
+TEST_F(MiscTest, FieldOptions) {
+  // Try setting field options.
+
+  FileDescriptorProto file_proto;
+  file_proto.set_name("foo.proto");
+
+  DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
+  AddField(message_proto, "foo", 1,
+           FieldDescriptorProto::LABEL_OPTIONAL,
+           FieldDescriptorProto::TYPE_INT32);
+  FieldDescriptorProto* bar_proto =
+    AddField(message_proto, "bar", 2,
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_INT32);
+
+  FieldOptions* options = bar_proto->mutable_options();
+  options->set_ctype(FieldOptions::CORD);
+
+  // Build the descriptors and get the pointers.
+  DescriptorPool pool;
+  const FileDescriptor* file = pool.BuildFile(file_proto);
+  ASSERT_TRUE(file != NULL);
+
+  ASSERT_EQ(1, file->message_type_count());
+  const Descriptor* message = file->message_type(0);
+
+  ASSERT_EQ(2, message->field_count());
+  const FieldDescriptor* foo = message->field(0);
+  const FieldDescriptor* bar = message->field(1);
+
+  // "foo" had no options set, so it should return the default options.
+  EXPECT_EQ(&FieldOptions::default_instance(), &foo->options());
+
+  // "bar" had options set.
+  EXPECT_NE(&FieldOptions::default_instance(), options);
+  EXPECT_TRUE(bar->options().has_ctype());
+  EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
+}
+
+// ===================================================================
+
+// The tests below trigger every unique call to AddError() in descriptor.cc,
+// in the order in which they appear in that file.  I'm using TextFormat here
+// to specify the input descriptors because building them using code would
+// be too bulky.
+
+class MockErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+  MockErrorCollector() {}
+  ~MockErrorCollector() {}
+
+  string text_;
+
+  // implements ErrorCollector ---------------------------------------
+  void AddError(const string& filename,
+                const string& element_name, const Message* descriptor,
+                ErrorLocation location, const string& message) {
+    const char* location_name = NULL;
+    switch (location) {
+      case NAME         : location_name = "NAME"         ; break;
+      case NUMBER       : location_name = "NUMBER"       ; break;
+      case TYPE         : location_name = "TYPE"         ; break;
+      case EXTENDEE     : location_name = "EXTENDEE"     ; break;
+      case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
+      case INPUT_TYPE   : location_name = "INPUT_TYPE"   ; break;
+      case OUTPUT_TYPE  : location_name = "OUTPUT_TYPE"  ; break;
+      case OTHER        : location_name = "OTHER"        ; break;
+    }
+
+    strings::SubstituteAndAppend(
+      &text_, "$0: $1: $2: $3\n",
+      filename, element_name, location_name, message);
+  }
+};
+
+class ValidationErrorTest : public testing::Test {
+ protected:
+  // Parse file_text as a FileDescriptorProto in text format and add it
+  // to the DescriptorPool.  Expect no errors.
+  void BuildFile(const string& file_text) {
+    FileDescriptorProto file_proto;
+    ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+    ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
+  }
+
+  // Parse file_text as a FileDescriptorProto in text format and add it
+  // to the DescriptorPool.  Expect errors to be produced which match the
+  // given error text.
+  void BuildFileWithErrors(const string& file_text,
+                           const string& expected_errors) {
+    FileDescriptorProto file_proto;
+    ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+
+    MockErrorCollector error_collector;
+    EXPECT_TRUE(
+      pool_.BuildFileCollectingErrors(file_proto, &error_collector) == NULL);
+    EXPECT_EQ(expected_errors, error_collector.text_);
+  }
+
+  DescriptorPool pool_;
+};
+
+TEST_F(ValidationErrorTest, AlreadyDefined) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { name: \"Foo\" }"
+    "message_type { name: \"Foo\" }",
+
+    "foo.proto: Foo: NAME: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "package: \"foo.bar\" "
+    "message_type { name: \"Foo\" }"
+    "message_type { name: \"Foo\" }",
+
+    "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in "
+      "\"foo.bar\".\n");
+}
+
+TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) {
+  BuildFile(
+    "name: \"foo.proto\" "
+    "message_type { name: \"Foo\" }");
+
+  BuildFileWithErrors(
+    "name: \"bar.proto\" "
+    "message_type { name: \"Foo\" }",
+
+    "bar.proto: Foo: NAME: \"Foo\" is already defined in file "
+      "\"foo.proto\".\n");
+}
+
+TEST_F(ValidationErrorTest, PackageAlreadyDefined) {
+  BuildFile(
+    "name: \"foo.proto\" "
+    "message_type { name: \"foo\" }");
+  BuildFileWithErrors(
+    "name: \"bar.proto\" "
+    "package: \"foo.bar\"",
+
+    "bar.proto: foo: NAME: \"foo\" is already defined (as something other "
+      "than a package) in file \"foo.proto\".\n");
+}
+
+TEST_F(ValidationErrorTest, MissingName) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { }",
+
+    "foo.proto: : NAME: Missing name.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidName) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { name: \"$\" }",
+
+    "foo.proto: $: NAME: \"$\" is not a valid identifier.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidPackageName) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "package: \"foo.$\"",
+
+    "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
+}
+
+TEST_F(ValidationErrorTest, MissingFileName) {
+  BuildFileWithErrors(
+    "",
+
+    ": : OTHER: Missing field: FileDescriptorProto.name.\n");
+}
+
+TEST_F(ValidationErrorTest, DupeDependency) {
+  BuildFile("name: \"foo.proto\"");
+  BuildFileWithErrors(
+    "name: \"bar.proto\" "
+    "dependency: \"foo.proto\" "
+    "dependency: \"foo.proto\" ",
+
+    "bar.proto: bar.proto: OTHER: Import \"foo.proto\" was listed twice.\n");
+}
+
+TEST_F(ValidationErrorTest, UnknownDependency) {
+  BuildFileWithErrors(
+    "name: \"bar.proto\" "
+    "dependency: \"foo.proto\" ",
+
+    "bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n");
+}
+
+TEST_F(ValidationErrorTest, DupeFile) {
+  BuildFile(
+    "name: \"foo.proto\" "
+    "message_type { name: \"Foo\" }");
+  // Note:  We should *not* get redundant errors about "Foo" already being
+  //   defined.
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { name: \"Foo\" }",
+
+    "foo.proto: foo.proto: OTHER: A file with this name is already in the "
+      "pool.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldInExtensionRange) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name: \"foo\" number:  9 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "  field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "  field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "  field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "  extension_range { start: 10 end: 20 }"
+    "}",
+
+    "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field "
+      "\"bar\" (10).\n"
+    "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field "
+      "\"baz\" (19).\n");
+}
+
+TEST_F(ValidationErrorTest, OverlappingExtensionRanges) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension_range { start: 10 end: 20 }"
+    "  extension_range { start: 20 end: 30 }"
+    "  extension_range { start: 19 end: 21 }"
+    "}",
+
+    "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
+      "already-defined range 10 to 19.\n"
+    "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
+      "already-defined range 20 to 29.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidDefaults) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+
+    // Invalid number.
+    "  field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32"
+    "          default_value: \"abc\" }"
+
+    // Empty default value.
+    "  field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32"
+    "          default_value: \"\" }"
+
+    // Invalid boolean.
+    "  field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL"
+    "          default_value: \"abc\" }"
+
+    // Messages can't have defaults.
+    "  field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: TYPE_MESSAGE"
+    "          default_value: \"abc\" type_name: \"Foo\" }"
+
+    // Same thing, but we don't know that this field has message type until
+    // we look up the type name.
+    "  field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
+    "          default_value: \"abc\" type_name: \"Foo\" }"
+    "}",
+
+    "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value.\n"
+    "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value.\n"
+    "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
+      "false.\n"
+    "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
+    "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
+      "values.\n");
+}
+
+TEST_F(ValidationErrorTest, NegativeFieldNumber) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "}",
+
+    "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n");
+}
+
+TEST_F(ValidationErrorTest, HugeFieldNumber) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name: \"foo\" number: 0x70000000 "
+    "          label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "}",
+
+    "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than "
+      "536870911.\n");
+}
+
+TEST_F(ValidationErrorTest, ReservedFieldNumber) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "  field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "  field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "  field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "}",
+
+    "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are "
+      "reserved for the protocol buffer library implementation.\n"
+    "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are "
+      "reserved for the protocol buffer library implementation.\n");
+}
+
+TEST_F(ValidationErrorTest, ExtensionMissingExtendee) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
+    "              type_name: \"Foo\" }"
+    "}",
+
+    "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for "
+      "extension field.\n");
+}
+
+TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Bar\""
+    "  extension_range { start: 1 end: 2 }"
+    "}"
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
+    "          type_name: \"Foo\" extendee: \"Bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for "
+      "non-extension field.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldNumberConflict) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "  field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "}",
+
+    "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in "
+      "\"Foo\" by field \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, BadMessageSetExtensionType) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"MessageSet\""
+    "  options { message_set_wire_format: true }"
+    "  extension_range { start: 4 end: 5 }"
+    "}"
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32"
+    "              extendee: \"MessageSet\" }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
+      "messages.\n");
+}
+
+TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"MessageSet\""
+    "  options { message_set_wire_format: true }"
+    "  extension_range { start: 4 end: 5 }"
+    "}"
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension { name:\"foo\" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE"
+    "              type_name: \"Foo\" extendee: \"MessageSet\" }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
+      "messages.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldInMessageSet) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  options { message_set_wire_format: true }"
+    "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "}",
+
+    "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only "
+      "extensions.\n");
+}
+
+TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension_range { start: -10 end: -1 }"
+    "}",
+
+    "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n");
+}
+
+TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension_range { start: 1 end: 0x70000000 }"
+    "}",
+
+    "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than "
+      "536870911.\n");
+}
+
+TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension_range { start: 10 end: 10 }"
+    "  extension_range { start: 10 end: 5 }"
+    "}",
+
+    "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
+      "start number.\n"
+    "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
+      "start number.\n");
+}
+
+TEST_F(ValidationErrorTest, EmptyEnum) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "enum_type { name: \"Foo\" }"
+    // Also use the empty enum in a message to make sure there are no crashes
+    // during validation (possible if the code attempts to derive a default
+    // value for the field).
+    "message_type {"
+    "  name: \"Bar\""
+    "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type_name:\"Foo\" }"
+    "  field { name: \"bar\" number: 2 label:LABEL_OPTIONAL type_name:\"Foo\" "
+    "          default_value: \"NO_SUCH_VALUE\" }"
+    "}",
+
+    "foo.proto: Foo: NAME: Enums must contain at least one value.\n"
+    "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named "
+      "\"NO_SUCH_VALUE\".\n");
+}
+
+TEST_F(ValidationErrorTest, UndefinedExtendee) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+    "              extendee: \"Bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, NonMessageExtendee) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }"
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+    "              extendee: \"Bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n");
+}
+
+TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Bar\""
+    "}"
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+    "              extendee: \"Bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension "
+      "number.\n");
+}
+
+TEST_F(ValidationErrorTest, UndefinedFieldType) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
+  BuildFile(
+    "name: \"bar.proto\" "
+    "message_type { name: \"Bar\" } ");
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+    "}",
+    "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
+      "which is not imported by \"foo.proto\".  To use it here, please add the "
+      "necessary import.\n");
+}
+
+TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
+  // The following should produce an error that Bar.Baz is not defined:
+  //   message Bar { message Baz {} }
+  //   message Foo {
+  //     message Bar {
+  //       // Placing "message Baz{}" here, or removing Foo.Bar altogether,
+  //       // would fix the error.
+  //     }
+  //     optional Bar.Baz baz = 1;
+  //   }
+  // An one point the lookup code incorrectly did not produce an error in this
+  // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first,
+  // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually
+  // refer to the inner Bar, not the outer one.
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Bar\""
+    "  nested_type { name: \"Baz\" }"
+    "}"
+    "message_type {"
+    "  name: \"Foo\""
+    "  nested_type { name: \"Bar\" }"
+    "  field { name:\"baz\" number:1 label:LABEL_OPTIONAL"
+    "          type_name:\"Bar.Baz\" }"
+    "}",
+
+    "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
+  // Imagine we have the following:
+  //
+  // foo.proto:
+  //   package foo.bar;
+  // bar.proto:
+  //   package foo.bar;
+  //   import "foo.proto";
+  //   message Bar {}
+  // baz.proto:
+  //   package foo;
+  //   import "bar.proto"
+  //   message Baz { optional bar.Bar qux = 1; }
+  //
+  // When validating baz.proto, we will look up "bar.Bar".  As part of this
+  // lookup, we first lookup "bar" then try to find "Bar" within it.  "bar"
+  // should resolve to "foo.bar".  Note, though, that "foo.bar" was originally
+  // defined in foo.proto, which is not a direct dependency of baz.proto.  The
+  // implementation of FindSymbol() normally only returns symbols in direct
+  // dependencies, not indirect ones.  This test insures that this does not
+  // prevent it from finding "foo.bar".
+
+  BuildFile(
+    "name: \"foo.proto\" "
+    "package: \"foo.bar\" ");
+  BuildFile(
+    "name: \"bar.proto\" "
+    "package: \"foo.bar\" "
+    "dependency: \"foo.proto\" "
+    "message_type { name: \"Bar\" }");
+  BuildFile(
+    "name: \"baz.proto\" "
+    "package: \"foo\" "
+    "dependency: \"bar.proto\" "
+    "message_type { "
+    "  name: \"Baz\" "
+    "  field { name:\"qux\" number:1 label:LABEL_OPTIONAL "
+    "          type_name:\"bar.Bar\" }"
+    "}");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeNotAType) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"bar\" }"
+    "  field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: \"bar\" is not a type.\n");
+}
+
+TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { name: \"Bar\" } "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM"
+    "          type_name:\"Bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n");
+}
+
+TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE"
+    "          type_name:\"Bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n");
+}
+
+TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
+    "          default_value:\"NO_SUCH_VALUE\" }"
+    "}",
+
+    "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named "
+      "\"NO_SUCH_VALUE\".\n");
+}
+
+TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+    "          type_name:\"Foo\" }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n");
+}
+
+TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: Field with message or enum type missing "
+      "type_name.\n");
+}
+
+TEST_F(ValidationErrorTest, InputTypeNotDefined) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { name: \"Foo\" } "
+    "service {"
+    "  name: \"TestService\""
+    "  method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
+    "}",
+
+    "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { name: \"Foo\" } "
+    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+    "service {"
+    "  name: \"TestService\""
+    "  method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
+    "}",
+
+    "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n");
+}
+
+TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { name: \"Foo\" } "
+    "service {"
+    "  name: \"TestService\""
+    "  method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
+    "}",
+
+    "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { name: \"Foo\" } "
+    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+    "service {"
+    "  name: \"TestService\""
+    "  method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
+    "}",
+
+    "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n");
+}
+
+TEST_F(ValidationErrorTest, RollbackAfterError) {
+  // Build a file which contains every kind of construct but references an
+  // undefined type.  All these constructs will be added to the symbol table
+  // before the undefined type error is noticed.  The DescriptorPool will then
+  // have to roll everything back.
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
+    "} "
+    "enum_type {"
+    "  name: \"TestEnum\""
+    "  value { name:\"BAR\" number:1 }"
+    "} "
+    "service {"
+    "  name: \"TestService\""
+    "  method {"
+    "    name: \"Baz\""
+    "    input_type: \"NoSuchType\""    // error
+    "    output_type: \"TestMessage\""
+    "  }"
+    "}",
+
+    "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n");
+
+  // Make sure that if we build the same file again with the error fixed,
+  // it works.  If the above rollback was incomplete, then some symbols will
+  // be left defined, and this second attempt will fail since it tries to
+  // re-define the same symbols.
+  BuildFile(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
+    "} "
+    "enum_type {"
+    "  name: \"TestEnum\""
+    "  value { name:\"BAR\" number:1 }"
+    "} "
+    "service {"
+    "  name: \"TestService\""
+    "  method { name:\"Baz\""
+    "           input_type:\"TestMessage\""
+    "           output_type:\"TestMessage\" }"
+    "}");
+}
+
+TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
+  // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is
+  // provided.
+
+  FileDescriptorProto file_proto;
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "name: \"foo.proto\" "
+    "message_type { name: \"Foo\" } "
+    "message_type { name: \"Foo\" } ",
+    &file_proto));
+
+  vector<string> errors;
+
+  {
+    ScopedMemoryLog log;
+    EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL);
+    errors = log.GetMessages(ERROR);
+  }
+
+  ASSERT_EQ(2, errors.size());
+
+  EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]);
+  EXPECT_EQ("  Foo: \"Foo\" is already defined.", errors[1]);
+}
+
+// ===================================================================
+// DescriptorDatabase
+
+static void AddToDatabase(SimpleDescriptorDatabase* database,
+                          const char* file_text) {
+  FileDescriptorProto file_proto;
+  EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+  database->Add(file_proto);
+}
+
+class DatabaseBackedPoolTest : public testing::Test {
+ protected:
+  DatabaseBackedPoolTest() {}
+
+  SimpleDescriptorDatabase database_;
+
+  virtual void SetUp() {
+    AddToDatabase(&database_,
+      "name: \"foo.proto\" "
+      "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } "
+      "enum_type { name:\"TestEnum\" value { name:\"DUMMY\" number:0 } } "
+      "service { name:\"TestService\" } ");
+    AddToDatabase(&database_,
+      "name: \"bar.proto\" "
+      "dependency: \"foo.proto\" "
+      "message_type { name:\"Bar\" } "
+      "extension { name:\"foo_ext\" extendee: \".Foo\" number:5 "
+      "            label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+  }
+
+  // We can't inject a file containing errors into a DescriptorPool, so we
+  // need an actual mock DescriptorDatabase to test errors.
+  class ErrorDescriptorDatabase : public DescriptorDatabase {
+   public:
+    ErrorDescriptorDatabase() {}
+    ~ErrorDescriptorDatabase() {}
+
+    // implements DescriptorDatabase ---------------------------------
+    bool FindFileByName(const string& filename,
+                        FileDescriptorProto* output) {
+      // error.proto and error2.proto cyclically import each other.
+      if (filename == "error.proto") {
+        output->Clear();
+        output->set_name("error.proto");
+        output->add_dependency("error2.proto");
+        return true;
+      } else if (filename == "error2.proto") {
+        output->Clear();
+        output->set_name("error2.proto");
+        output->add_dependency("error.proto");
+        return true;
+      } else {
+        return false;
+      }
+    }
+    bool FindFileContainingSymbol(const string& symbol_name,
+                                  FileDescriptorProto* output) {
+      return false;
+    }
+    bool FindFileContainingExtension(const string& containing_type,
+                                     int field_number,
+                                     FileDescriptorProto* output) {
+      return false;
+    }
+  };
+
+  // A DescriptorDatabase that counts how many times each method has been
+  // called and forwards to some other DescriptorDatabase.
+  class CallCountingDatabase : public DescriptorDatabase {
+   public:
+    CallCountingDatabase(DescriptorDatabase* wrapped_db)
+      : wrapped_db_(wrapped_db) {
+      Clear();
+    }
+    ~CallCountingDatabase() {}
+
+    DescriptorDatabase* wrapped_db_;
+
+    int call_count_;
+
+    void Clear() {
+      call_count_ = 0;
+    }
+
+    // implements DescriptorDatabase ---------------------------------
+    bool FindFileByName(const string& filename,
+                        FileDescriptorProto* output) {
+      ++call_count_;
+      return wrapped_db_->FindFileByName(filename, output);
+    }
+    bool FindFileContainingSymbol(const string& symbol_name,
+                                  FileDescriptorProto* output) {
+      ++call_count_;
+      return wrapped_db_->FindFileContainingSymbol(symbol_name, output);
+    }
+    bool FindFileContainingExtension(const string& containing_type,
+                                     int field_number,
+                                     FileDescriptorProto* output) {
+      ++call_count_;
+      return wrapped_db_->FindFileContainingExtension(
+        containing_type, field_number, output);
+    }
+  };
+
+  // A DescriptorDatabase which falsely always returns foo.proto when searching
+  // for any symbol or extension number.  This shouldn't cause the
+  // DescriptorPool to reload foo.proto if it is already loaded.
+  class FalsePositiveDatabase : public DescriptorDatabase {
+   public:
+    FalsePositiveDatabase(DescriptorDatabase* wrapped_db)
+      : wrapped_db_(wrapped_db) {}
+    ~FalsePositiveDatabase() {}
+
+    DescriptorDatabase* wrapped_db_;
+
+    // implements DescriptorDatabase ---------------------------------
+    bool FindFileByName(const string& filename,
+                        FileDescriptorProto* output) {
+      return wrapped_db_->FindFileByName(filename, output);
+    }
+    bool FindFileContainingSymbol(const string& symbol_name,
+                                  FileDescriptorProto* output) {
+      return FindFileByName("foo.proto", output);
+    }
+    bool FindFileContainingExtension(const string& containing_type,
+                                     int field_number,
+                                     FileDescriptorProto* output) {
+      return FindFileByName("foo.proto", output);
+    }
+  };
+};
+
+TEST_F(DatabaseBackedPoolTest, FindFileByName) {
+  DescriptorPool pool(&database_);
+
+  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
+  ASSERT_TRUE(foo != NULL);
+  EXPECT_EQ("foo.proto", foo->name());
+  ASSERT_EQ(1, foo->message_type_count());
+  EXPECT_EQ("Foo", foo->message_type(0)->name());
+
+  EXPECT_EQ(foo, pool.FindFileByName("foo.proto"));
+
+  EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == NULL);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) {
+  DescriptorPool pool(&database_);
+
+  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
+  ASSERT_TRUE(foo != NULL);
+  EXPECT_EQ("foo.proto", foo->name());
+  ASSERT_EQ(1, foo->message_type_count());
+  EXPECT_EQ("Foo", foo->message_type(0)->name());
+
+  const FileDescriptor* bar = pool.FindFileByName("bar.proto");
+  ASSERT_TRUE(bar != NULL);
+  EXPECT_EQ("bar.proto", bar->name());
+  ASSERT_EQ(1, bar->message_type_count());
+  EXPECT_EQ("Bar", bar->message_type(0)->name());
+
+  ASSERT_EQ(1, bar->dependency_count());
+  EXPECT_EQ(foo, bar->dependency(0));
+}
+
+TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) {
+  DescriptorPool pool(&database_);
+
+  const FileDescriptor* bar = pool.FindFileByName("bar.proto");
+  ASSERT_TRUE(bar != NULL);
+  EXPECT_EQ("bar.proto", bar->name());
+  ASSERT_EQ(1, bar->message_type_count());
+  ASSERT_EQ("Bar", bar->message_type(0)->name());
+
+  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
+  ASSERT_TRUE(foo != NULL);
+  EXPECT_EQ("foo.proto", foo->name());
+  ASSERT_EQ(1, foo->message_type_count());
+  ASSERT_EQ("Foo", foo->message_type(0)->name());
+
+  ASSERT_EQ(1, bar->dependency_count());
+  EXPECT_EQ(foo, bar->dependency(0));
+}
+
+TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) {
+  DescriptorPool pool(&database_);
+
+  const FileDescriptor* file = pool.FindFileContainingSymbol("Foo");
+  ASSERT_TRUE(file != NULL);
+  EXPECT_EQ("foo.proto", file->name());
+  EXPECT_EQ(file, pool.FindFileByName("foo.proto"));
+
+  EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == NULL);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) {
+  DescriptorPool pool(&database_);
+
+  const Descriptor* type = pool.FindMessageTypeByName("Foo");
+  ASSERT_TRUE(type != NULL);
+  EXPECT_EQ("Foo", type->name());
+  EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto"));
+
+  EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == NULL);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) {
+  DescriptorPool pool(&database_);
+
+  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+  ASSERT_TRUE(foo != NULL);
+
+  const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5);
+  ASSERT_TRUE(extension != NULL);
+  EXPECT_EQ("foo_ext", extension->name());
+  EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto"));
+
+  EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == NULL);
+}
+
+TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
+  ErrorDescriptorDatabase error_database;
+  DescriptorPool pool(&error_database);
+
+  vector<string> errors;
+
+  {
+    ScopedMemoryLog log;
+    EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
+    errors = log.GetMessages(ERROR);
+  }
+
+  EXPECT_FALSE(errors.empty());
+}
+
+TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
+  ErrorDescriptorDatabase error_database;
+  MockErrorCollector error_collector;
+  DescriptorPool pool(&error_database, &error_collector);
+
+  EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
+  EXPECT_EQ(
+    "error.proto: error.proto: OTHER: File recursively imports itself: "
+      "error.proto -> error2.proto -> error.proto\n"
+    "error2.proto: error2.proto: OTHER: Import \"error.proto\" was not "
+      "found or had errors.\n"
+    "error.proto: error.proto: OTHER: Import \"error2.proto\" was not "
+      "found or had errors.\n",
+    error_collector.text_);
+}
+
+TEST_F(DatabaseBackedPoolTest, UnittestProto) {
+  // Try to load all of unittest.proto from a DescriptorDatabase.  This should
+  // thoroughly test all paths through DescriptorBuilder to insure that there
+  // are no deadlocking problems when pool_->mutex_ is non-NULL.
+  const FileDescriptor* original_file =
+    protobuf_unittest::TestAllTypes::descriptor()->file();
+
+  DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
+  DescriptorPool pool(&database);
+  const FileDescriptor* file_from_database =
+    pool.FindFileByName(original_file->name());
+
+  ASSERT_TRUE(file_from_database != NULL);
+
+  FileDescriptorProto original_file_proto;
+  original_file->CopyTo(&original_file_proto);
+
+  FileDescriptorProto file_from_database_proto;
+  file_from_database->CopyTo(&file_from_database_proto);
+
+  EXPECT_EQ(original_file_proto.DebugString(),
+            file_from_database_proto.DebugString());
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
+  // Searching for a child of an existing descriptor should never fall back
+  // to the DescriptorDatabase even if it isn't found, because we know all
+  // children are already loaded.
+  CallCountingDatabase call_counter(&database_);
+  DescriptorPool pool(&call_counter);
+
+  const FileDescriptor* file = pool.FindFileByName("foo.proto");
+  ASSERT_TRUE(file != NULL);
+  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+  ASSERT_TRUE(foo != NULL);
+  const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
+  ASSERT_TRUE(test_enum != NULL);
+  const ServiceDescriptor* test_service = pool.FindServiceByName("TestService");
+  ASSERT_TRUE(test_service != NULL);
+
+  EXPECT_NE(0, call_counter.call_count_);
+  call_counter.Clear();
+
+  EXPECT_TRUE(foo->FindFieldByName("no_such_field") == NULL);
+  EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == NULL);
+  EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == NULL);
+  EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == NULL);
+  EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
+  EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == NULL);
+  EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == NULL);
+
+  EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == NULL);
+  EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == NULL);
+  EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
+  EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL);
+  EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL);
+  EXPECT_EQ(0, call_counter.call_count_);
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
+  // If FindFileContainingSymbol() or FindFileContainingExtension() return a
+  // file that is already in the DescriptorPool, it should not attempt to
+  // reload the file.
+  FalsePositiveDatabase false_positive_database(&database_);
+  MockErrorCollector error_collector;
+  DescriptorPool pool(&false_positive_database, &error_collector);
+
+  // First make sure foo.proto is loaded.
+  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+  ASSERT_TRUE(foo != NULL);
+
+  // Try inducing false positives.
+  EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == NULL);
+  EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == NULL);
+
+  // No errors should have been reported.  (If foo.proto was incorrectly
+  // loaded multiple times, errors would have been reported.)
+  EXPECT_EQ("", error_collector.text_);
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
+  ErrorDescriptorDatabase error_database;
+  MockErrorCollector error_collector;
+  DescriptorPool pool(&error_database, &error_collector);
+
+  EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
+  error_collector.text_.clear();
+  EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
+  EXPECT_EQ("", error_collector.text_);
+}
+
+}  // anonymous namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
new file mode 100644
index 0000000..43e2451
--- /dev/null
+++ b/src/google/protobuf/dynamic_message.cc
@@ -0,0 +1,475 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// DynamicMessage is implemented by constructing a data structure which
+// has roughly the same memory layout as a generated message would have.
+// 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.
+//
+// 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
+// down side is that this is a low-level memory management hack which
+// can be tricky to get right.
+//
+// As mentioned in the header, we only expose a DynamicMessageFactory
+// publicly, not the DynamicMessage class itself.  This is because
+// GenericMessageReflection wants to have a pointer to a "default"
+// copy of the class, with all fields initialized to their default
+// values.  We only want to construct one of these per message type,
+// so DynamicMessageFactory stores a cache of default messages for
+// each type it sees (each unique Descriptor pointer).  The code
+// refers to the "default" copy of the class as the "prototype".
+//
+// Note on memory allocation:  This module often calls "operator new()"
+// to allocate untyped memory, rather than calling something like
+// "new uint8[]".  This is because "operator new()" means "Give me some
+// space which I can use as I please." while "new uint8[]" means "Give
+// me an array of 8-bit integers.".  In practice, the later may return
+// a pointer that is not aligned correctly for general use.  I believe
+// Item 8 of "More Effective C++" discusses this in more detail, though
+// I don't have the book on me right now so I'm not sure.
+
+#include <algorithm>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/stubs/common.h>
+
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format.h>
+
+namespace google {
+namespace protobuf {
+
+using internal::WireFormat;
+using internal::ExtensionSet;
+using internal::GeneratedMessageReflection;
+using internal::GenericRepeatedField;
+
+
+// ===================================================================
+// Some helper tables and functions...
+
+namespace {
+
+// Compute the byte size of the in-memory representation of the field.
+int FieldSpaceUsed(const FieldDescriptor* field) {
+  typedef FieldDescriptor FD;  // avoid line wrapping
+  if (field->label() == FD::LABEL_REPEATED) {
+    switch (field->cpp_type()) {
+      case FD::CPPTYPE_INT32  : return sizeof(RepeatedField<int32   >);
+      case FD::CPPTYPE_INT64  : return sizeof(RepeatedField<int64   >);
+      case FD::CPPTYPE_UINT32 : return sizeof(RepeatedField<uint32  >);
+      case FD::CPPTYPE_UINT64 : return sizeof(RepeatedField<uint64  >);
+      case FD::CPPTYPE_DOUBLE : return sizeof(RepeatedField<double  >);
+      case FD::CPPTYPE_FLOAT  : return sizeof(RepeatedField<float   >);
+      case FD::CPPTYPE_BOOL   : return sizeof(RepeatedField<bool    >);
+      case FD::CPPTYPE_ENUM   : return sizeof(RepeatedField<int     >);
+      case FD::CPPTYPE_MESSAGE: return sizeof(RepeatedPtrField<Message>);
+
+      case FD::CPPTYPE_STRING:
+          return sizeof(RepeatedPtrField<string>);
+        break;
+    }
+  } else {
+    switch (field->cpp_type()) {
+      case FD::CPPTYPE_INT32  : return sizeof(int32   );
+      case FD::CPPTYPE_INT64  : return sizeof(int64   );
+      case FD::CPPTYPE_UINT32 : return sizeof(uint32  );
+      case FD::CPPTYPE_UINT64 : return sizeof(uint64  );
+      case FD::CPPTYPE_DOUBLE : return sizeof(double  );
+      case FD::CPPTYPE_FLOAT  : return sizeof(float   );
+      case FD::CPPTYPE_BOOL   : return sizeof(bool    );
+      case FD::CPPTYPE_ENUM   : return sizeof(int     );
+      case FD::CPPTYPE_MESSAGE: return sizeof(Message*);
+
+      case FD::CPPTYPE_STRING:
+          return sizeof(string*);
+        break;
+    }
+  }
+
+  GOOGLE_LOG(DFATAL) << "Can't get here.";
+  return 0;
+}
+
+struct DescendingFieldSizeOrder {
+  inline bool operator()(const FieldDescriptor* a,
+                         const FieldDescriptor* b) {
+    // All repeated fields come first.
+    if (a->is_repeated()) {
+      if (b->is_repeated()) {
+        // Repeated fields and are not ordered with respect to each other.
+        return false;
+      } else {
+        return true;
+      }
+    } else if (b->is_repeated()) {
+      return false;
+    } else {
+      // Remaining fields in descending order by size.
+      return FieldSpaceUsed(a) > FieldSpaceUsed(b);
+    }
+  }
+};
+
+inline int DivideRoundingUp(int i, int j) {
+  return (i + (j - 1)) / j;
+}
+
+#define bitsizeof(T) (sizeof(T) * 8)
+
+}  // namespace
+
+// ===================================================================
+
+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);
+  ~DynamicMessage();
+
+  // Called on the prototype after construction to initialize message fields.
+  void CrossLinkPrototypes(DynamicMessageFactory* factory);
+
+  // implements Message ----------------------------------------------
+
+  Message* New() const;
+
+  int GetCachedSize() const;
+  void SetCachedSize(int size) const;
+
+  const Descriptor* GetDescriptor() const;
+  const Reflection* GetReflection() const;
+  Reflection* GetReflection();
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
+
+  inline bool is_prototype() { return base_ == prototype_base_; }
+
+  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_;
+
+  // 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),
+    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
+  // constructors.  If you haven't heard of placement new, I suggest Googling
+  // it now.  We use placement new even for primitive types that don't have
+  // constructors for consistency.  (In theory, placement new should be used
+  // 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.)
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    const FieldDescriptor* field = descriptor->field(i);
+    void* field_ptr = base + offsets[i];
+    switch (field->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, TYPE)                                           \
+      case FieldDescriptor::CPPTYPE_##CPPTYPE:                               \
+        if (!field->is_repeated()) {                                         \
+          new(field_ptr) TYPE(field->default_value_##TYPE());                \
+        } else {                                                             \
+          new(field_ptr) RepeatedField<TYPE>();                              \
+        }                                                                    \
+        break;
+
+      HANDLE_TYPE(INT32 , int32 );
+      HANDLE_TYPE(INT64 , int64 );
+      HANDLE_TYPE(UINT32, uint32);
+      HANDLE_TYPE(UINT64, uint64);
+      HANDLE_TYPE(DOUBLE, double);
+      HANDLE_TYPE(FLOAT , float );
+      HANDLE_TYPE(BOOL  , bool  );
+#undef HANDLE_TYPE
+
+      case FieldDescriptor::CPPTYPE_ENUM:
+        if (!field->is_repeated()) {
+          new(field_ptr) int(field->default_value_enum()->number());
+        } else {
+          new(field_ptr) RepeatedField<int>();
+        }
+        break;
+
+      case FieldDescriptor::CPPTYPE_STRING:
+          if (!field->is_repeated()) {
+            if (is_prototype()) {
+              new(field_ptr) const string*(&field->default_value_string());
+            } else {
+              string* default_value =
+                *reinterpret_cast<string* const*>(
+                  prototype_base + offsets[i]);
+              new(field_ptr) string*(default_value);
+            }
+          } else {
+            new(field_ptr) RepeatedPtrField<string>();
+          }
+        break;
+
+      case FieldDescriptor::CPPTYPE_MESSAGE: {
+        // If this object is the prototype, its CPPTYPE_MESSAGE fields
+        // must be initialized later, in CrossLinkPrototypes(), so we don't
+        // initialize them here.
+        if (!is_prototype()) {
+          if (!field->is_repeated()) {
+            new(field_ptr) Message*(NULL);
+          } else {
+            const RepeatedPtrField<Message>* prototype_field =
+              reinterpret_cast<const RepeatedPtrField<Message>*>(
+                prototype_base + offsets[i]);
+            new(field_ptr) RepeatedPtrField<Message>(
+              prototype_field->prototype());
+          }
+        }
+        break;
+      }
+    }
+  }
+}
+
+DynamicMessage::~DynamicMessage() {
+  // 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];
+
+    if (field->is_repeated()) {
+      GenericRepeatedField* field =
+        reinterpret_cast<GenericRepeatedField*>(field_ptr);
+      field->~GenericRepeatedField();
+
+    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+        string* ptr = *reinterpret_cast<string**>(field_ptr);
+        if (ptr != &field->default_value_string()) {
+          delete ptr;
+        }
+    } else if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) &&
+               !is_prototype()) {
+      Message* message = *reinterpret_cast<Message**>(field_ptr);
+      if (message != NULL) {
+        delete message;
+      }
+    }
+  }
+
+  // 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) {
+  // This should only be called on the prototype message.
+  GOOGLE_CHECK(is_prototype());
+
+  // 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];
+
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      // For fields with message types, we need to cross-link with the
+      // prototype for the field's type.
+      const Message* field_prototype =
+        factory->GetPrototype(field->message_type());
+
+      if (field->is_repeated()) {
+        // For repeated fields, we actually construct the RepeatedPtrField
+        // here, but only for fields with message types.  All other repeated
+        // fields are constructed in DynamicMessage's constructor.
+        new(field_ptr) RepeatedPtrField<Message>(field_prototype);
+      } else {
+        // For singular fields, the field is just a pointer which should
+        // point to the prototype.  (OK to const_cast here because the
+        // prototype itself will only be available const to the outside
+        // world.)
+        new(field_ptr) Message*(const_cast<Message*>(field_prototype));
+      }
+    }
+  }
+}
+
+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_);
+}
+
+int DynamicMessage::GetCachedSize() const {
+  return cached_byte_size_;
+}
+
+void DynamicMessage::SetCachedSize(int size) const {
+  // This is theoretically not thread-compatible, but in practice it works
+  // because if multiple threads write this simultaneously, they will be
+  // writing the exact same value.
+  cached_byte_size_ = size;
+}
+
+const Descriptor* DynamicMessage::GetDescriptor() const {
+  return descriptor_;
+}
+
+const Message::Reflection* DynamicMessage::GetReflection() const {
+  return &reflection_;
+}
+
+Message::Reflection* DynamicMessage::GetReflection() {
+  return &reflection_;
+}
+
+// ===================================================================
+
+struct DynamicMessageFactory::PrototypeMap {
+  typedef hash_map<const Descriptor*, const Message*> Map;
+  Map map_;
+};
+
+DynamicMessageFactory::DynamicMessageFactory()
+  : pool_(NULL), prototypes_(new PrototypeMap) {
+}
+
+DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
+  : pool_(pool), prototypes_(new PrototypeMap) {
+}
+
+DynamicMessageFactory::~DynamicMessageFactory() {
+  for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin();
+       iter != prototypes_->map_.end(); ++iter) {
+    delete iter->second;
+  }
+}
+
+
+const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
+  const Message** target = &prototypes_->map_[type];
+  if (*target != NULL) {
+    // Already exists.
+    return *target;
+  }
+
+  // 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.
+  // - An array of integers indicating the byte offset of each field within
+  //   this block.
+  // - A big bitfield containing a bit for each field indicating whether
+  //   or not that field is set.
+
+  // Compute size and offsets.
+  int* offsets = new int[type->field_count()];
+
+  // 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
+  // will end up properly-aligned, since all field sizes are powers of two or
+  // are multiples of the system word size.
+  scoped_array<const FieldDescriptor*> ordered_fields(
+    new const FieldDescriptor*[type->field_count()]);
+  for (int i = 0; i < type->field_count(); i++) {
+    ordered_fields[i] = type->field(i);
+  }
+  stable_sort(&ordered_fields[0], &ordered_fields[type->field_count()],
+              DescendingFieldSizeOrder());
+
+  // Decide all field offsets by packing in order.
+  int current_offset = 0;
+
+  for (int i = 0; i < type->field_count(); i++) {
+    offsets[ordered_fields[i]->index()] = current_offset;
+    current_offset += 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);
+
+  // Construct message.
+  DynamicMessage* result =
+    new DynamicMessage(type, base, base, size, offsets, pool_, this);
+  *target = result;
+  result->CrossLinkPrototypes(this);
+
+  return result;
+}
+
+}  // namespace protobuf
+
+}  // namespace google
diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h
new file mode 100644
index 0000000..e5a9f90
--- /dev/null
+++ b/src/google/protobuf/dynamic_message.h
@@ -0,0 +1,105 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Defines an implementation of Message which can emulate types which are not
+// known at compile-time.
+
+#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
+#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
+
+#include <google/protobuf/message.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// Defined in other files.
+class Descriptor;        // descriptor.h
+class DescriptorPool;    // descriptor.h
+
+// Constructs implementations of Message which can emulate types which are not
+// known at compile-time.
+//
+// Sometimes you want to be able to manipulate protocol types that you don't
+// know about at compile time.  It would be nice to be able to construct
+// a Message object which implements the message type given by any arbitrary
+// Descriptor.  DynamicMessage provides this.
+//
+// As it turns out, a DynamicMessage needs to construct extra
+// information about its type in order to operate.  Most of this information
+// can be shared between all DynamicMessages of the same type.  But, caching
+// this information in some sort of global map would be a bad idea, since
+// the cached information for a particular descriptor could outlive the
+// descriptor itself.  To avoid this problem, DynamicMessageFactory
+// encapsulates this "cache".  All DynamicMessages of the same type created
+// from the same factory will share the same support data.  Any Descriptors
+// used with a particular factory must outlive the factory.
+class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
+ public:
+  // Construct a DynamicMessageFactory that will search for extensions in
+  // the DescriptorPool in which the exendee is defined.
+  DynamicMessageFactory();
+
+  // Construct a DynamicMessageFactory that will search for extensions in
+  // the given DescriptorPool.
+  DynamicMessageFactory(const DescriptorPool* pool);
+  ~DynamicMessageFactory();
+
+  // implements MessageFactory ---------------------------------------
+
+  // Given a Descriptor, constructs the default (prototype) Message of that
+  // type.  You can then call that message's New() method to construct a
+  // mutable message of that type.
+  //
+  // Calling this method twice with the same Descriptor returns the same
+  // object.  The returned object remains property of the factory and will
+  // be destroyed when the factory is destroyed.  Also, any objects created
+  // by calling the prototype's New() method share some data with the
+  // prototype, so these must be destoyed before the DynamicMessageFactory
+  // is destroyed.
+  //
+  // The given descriptor must outlive the returned message, and hence must
+  // outlive the DynamicMessageFactory.
+  //
+  // Note that while GetPrototype() is idempotent, it is not const.  This
+  // implies that it is not thread-safe to call GetPrototype() on the same
+  // DynamicMessageFactory in two different threads simultaneously.  However,
+  // the returned objects are just as thread-safe as any other Message.
+  const Message* GetPrototype(const Descriptor* type);
+
+ private:
+  const DescriptorPool* pool_;
+
+  // This struct just contains a hash_map.  We can't #include <google/protobuf/stubs/hash.h> from
+  // this header due to hacks needed for hash_map portability in the open source
+  // release.  Namely, stubs/hash.h, which defines hash_map portably, is not a
+  // public header (for good reason), but dynamic_message.h is, and public
+  // headers may only #include other public headers.
+  struct PrototypeMap;
+  scoped_ptr<PrototypeMap> prototypes_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
+
diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc
new file mode 100644
index 0000000..5afac1f
--- /dev/null
+++ b/src/google/protobuf/dynamic_message_unittest.cc
@@ -0,0 +1,117 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Since the reflection interface for DynamicMessage is implemented by
+// GenericMessageReflection, the only thing we really have to test is
+// that DynamicMessage correctly sets up the information that
+// GenericMessageReflection needs to use.  So, we focus on that in this
+// test.  Other tests, such as generic_message_reflection_unittest and
+// reflection_ops_unittest, cover the rest of the functionality used by
+// DynamicMessage.
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/unittest.pb.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+class DynamicMessageTest : public testing::Test {
+ protected:
+  DescriptorPool pool_;
+  DynamicMessageFactory factory_;
+  const Descriptor* descriptor_;
+  const Message* prototype_;
+  const Descriptor* extensions_descriptor_;
+  const Message* extensions_prototype_;
+
+  DynamicMessageTest(): factory_(&pool_) {}
+
+  virtual void SetUp() {
+    // We want to make sure that DynamicMessage works (particularly with
+    // extensions) even if we use descriptors that are *not* from compiled-in
+    // types, so we make copies of the descriptors for unittest.proto and
+    // unittest_import.proto.
+    FileDescriptorProto unittest_file;
+    FileDescriptorProto unittest_import_file;
+
+    unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file);
+    unittest_import::ImportMessage::descriptor()->file()->CopyTo(
+      &unittest_import_file);
+
+    ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL);
+    ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL);
+
+    descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes");
+    ASSERT_TRUE(descriptor_ != NULL);
+    prototype_ = factory_.GetPrototype(descriptor_);
+
+    extensions_descriptor_ =
+      pool_.FindMessageTypeByName("protobuf_unittest.TestAllExtensions");
+    ASSERT_TRUE(extensions_descriptor_ != NULL);
+    extensions_prototype_ = factory_.GetPrototype(extensions_descriptor_);
+  }
+};
+
+TEST_F(DynamicMessageTest, Descriptor) {
+  // Check that the descriptor on the DynamicMessage matches the descriptor
+  // passed to GetPrototype().
+  EXPECT_EQ(prototype_->GetDescriptor(), descriptor_);
+}
+
+TEST_F(DynamicMessageTest, OnePrototype) {
+  // Check that requesting the same prototype twice produces the same object.
+  EXPECT_EQ(prototype_, factory_.GetPrototype(descriptor_));
+}
+
+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());
+}
+
+TEST_F(DynamicMessageTest, IndependentOffsets) {
+  // Check that all fields have independent offsets by setting each
+  // one to a unique value then checking that they all still have those
+  // unique values (i.e. they don't stomp each other).
+  scoped_ptr<Message> message(prototype_->New());
+  TestUtil::ReflectionTester reflection_tester(descriptor_);
+
+  reflection_tester.SetAllFieldsViaReflection(message->GetReflection());
+  reflection_tester.ExpectAllFieldsSetViaReflection(*message->GetReflection());
+}
+
+TEST_F(DynamicMessageTest, Extensions) {
+  // Check that extensions work.
+  scoped_ptr<Message> message(extensions_prototype_->New());
+  TestUtil::ReflectionTester reflection_tester(extensions_descriptor_);
+
+  reflection_tester.SetAllFieldsViaReflection(message->GetReflection());
+  reflection_tester.ExpectAllFieldsSetViaReflection(*message->GetReflection());
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
new file mode 100644
index 0000000..154f06f
--- /dev/null
+++ b/src/google/protobuf/extension_set.cc
@@ -0,0 +1,735 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/repeated_field.h>
+
+namespace google {
+namespace protobuf {
+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);
+  if (descriptor == NULL) {
+    // This extension doesn't exist, so we have to crash.  However, let's
+    // try to provide an informative error message.
+    if (descriptor_pool_ == DescriptorPool::generated_pool() &&
+        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 "
+                 << 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 "
+                    "message type?  This is not permitted; linkin-in message "
+                    "types cannot use non-linked-in extensions.  Try "
+                    "converting to a DynamicMessage first.";
+    } else {
+      // This is probably a DynamicMessage.
+      GOOGLE_LOG(FATAL) << ": No extension is registered for \""
+                 << 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 "
+                    "to DynamicMessageFactory's constructor.";
+    }
+  }
+  return descriptor;
+}
+
+const Message*
+ExtensionSet::GetPrototype(const Descriptor* message_type) const {
+  return message_factory_->GetPrototype(message_type);
+}
+
+// ===================================================================
+// Constructors and basic methods.
+
+ExtensionSet::ExtensionSet(const Descriptor* extendee,
+                           const DescriptorPool* pool,
+                           MessageFactory* factory)
+  : extendee_(extendee),
+    descriptor_pool_(pool),
+    message_factory_(factory) {
+}
+
+ExtensionSet::~ExtensionSet() {
+  for (map<int, Extension>::iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    iter->second.Free();
+  }
+}
+
+void ExtensionSet::AppendToList(vector<const FieldDescriptor*>* output) const {
+  for (map<int, Extension>::const_iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    bool has = false;
+    if (iter->second.descriptor->is_repeated()) {
+      has = iter->second.GetSize() > 0;
+    } else {
+      has = !iter->second.is_cleared;
+    }
+
+    if (has) {
+      output->push_back(iter->second.descriptor);
+    }
+  }
+}
+
+bool ExtensionSet::Has(int number) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) return false;
+  GOOGLE_DCHECK(!iter->second.descriptor->is_repeated());
+  return !iter->second.is_cleared;
+}
+
+int ExtensionSet::ExtensionSize(int number) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) return false;
+  return iter->second.GetSize();
+}
+
+void ExtensionSet::ClearExtension(int number) {
+  map<int, Extension>::iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) return;
+  iter->second.Clear();
+}
+
+// ===================================================================
+// Field accessors
+
+#define GOOGLE_DCHECK_TYPE(DESCRIPTOR, LABEL, CPPTYPE)                           \
+  GOOGLE_DCHECK_EQ(DESCRIPTOR->label(), FieldDescriptor::LABEL_##LABEL);         \
+  GOOGLE_DCHECK_EQ(DESCRIPTOR->cpp_type(), FieldDescriptor::CPPTYPE_##CPPTYPE)
+
+// -------------------------------------------------------------------
+// Primitives
+
+#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE)                   \
+                                                                               \
+LOWERCASE ExtensionSet::Get##CAMELCASE(int number) const {                     \
+  map<int, Extension>::const_iterator iter = extensions_.find(number);         \
+  if (iter == extensions_.end()) {                                             \
+    /* Not present.  Return the default value. */                              \
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);       \
+    GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, UPPERCASE);                              \
+    return descriptor->default_value_##LOWERCASE();                            \
+  } else {                                                                     \
+    GOOGLE_DCHECK_TYPE(iter->second.descriptor, OPTIONAL, UPPERCASE);                 \
+    return iter->second.LOWERCASE##_value;                                     \
+  }                                                                            \
+}                                                                              \
+                                                                               \
+void ExtensionSet::Set##CAMELCASE(int number, LOWERCASE value) {               \
+  Extension* extension = &extensions_[number];                                 \
+  if (extension->descriptor == NULL) {                                         \
+    /* Not previoulsy present.  Initialize it. */                              \
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);       \
+    GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, UPPERCASE);                              \
+    extension->descriptor = descriptor;                                        \
+    extension->LOWERCASE##_value = descriptor->default_value_##LOWERCASE();    \
+  } else {                                                                     \
+    GOOGLE_DCHECK_TYPE(extension->descriptor, OPTIONAL, UPPERCASE);                   \
+    extension->is_cleared = false;                                             \
+  }                                                                            \
+  extension->LOWERCASE##_value = value;                                        \
+}                                                                              \
+                                                                               \
+LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const {  \
+  map<int, Extension>::const_iterator iter = extensions_.find(number);         \
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
+  GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, UPPERCASE);                   \
+  return iter->second.repeated_##LOWERCASE##_value->Get(index);                \
+}                                                                              \
+                                                                               \
+void ExtensionSet::SetRepeated##CAMELCASE(                                     \
+    int number, int index, LOWERCASE value) {                                  \
+  map<int, Extension>::iterator iter = extensions_.find(number);               \
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
+  GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, UPPERCASE);                   \
+  iter->second.repeated_##LOWERCASE##_value->Set(index, value);                \
+}                                                                              \
+                                                                               \
+void ExtensionSet::Add##CAMELCASE(int number, LOWERCASE value) {               \
+  Extension* extension = &extensions_[number];                                 \
+  if (extension->descriptor == NULL) {                                         \
+    /* Not previoulsy present.  Initialize it. */                              \
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);       \
+    GOOGLE_DCHECK_TYPE(descriptor, REPEATED, UPPERCASE);                              \
+    extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>();  \
+    extension->descriptor = descriptor;                                        \
+  } else {                                                                     \
+    GOOGLE_DCHECK_TYPE(extension->descriptor, REPEATED, UPPERCASE);                   \
+  }                                                                            \
+  extension->repeated_##LOWERCASE##_value->Add(value);                         \
+}
+
+PRIMITIVE_ACCESSORS( INT32,  int32,  Int32)
+PRIMITIVE_ACCESSORS( INT64,  int64,  Int64)
+PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
+PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
+PRIMITIVE_ACCESSORS( FLOAT,  float,  Float)
+PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
+PRIMITIVE_ACCESSORS(  BOOL,   bool,   Bool)
+
+#undef PRIMITIVE_ACCESSORS
+
+// -------------------------------------------------------------------
+// Enums
+
+int ExtensionSet::GetEnum(int number) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) {
+    // Not present.  Return the default value.
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);
+    GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, ENUM);
+    return descriptor->default_value_enum()->number();
+  } else {
+    GOOGLE_DCHECK_TYPE(iter->second.descriptor, OPTIONAL, ENUM);
+    return iter->second.enum_value;
+  }
+}
+
+void ExtensionSet::SetEnum(int number, int value) {
+  Extension* extension = &extensions_[number];
+  if (extension->descriptor == NULL) {
+    // Not previoulsy present.  Initialize it.
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);
+    GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, ENUM);
+    extension->descriptor = descriptor;
+    extension->enum_value = descriptor->default_value_enum()->number();
+  } else {
+    GOOGLE_DCHECK_TYPE(extension->descriptor, OPTIONAL, ENUM);
+    extension->is_cleared = false;
+  }
+  GOOGLE_DCHECK(extension->descriptor->enum_type()->FindValueByNumber(value) != NULL);
+  extension->enum_value = value;
+}
+
+int ExtensionSet::GetRepeatedEnum(int number, int index) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+  GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, ENUM);
+  return iter->second.repeated_enum_value->Get(index);
+}
+
+void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
+  map<int, Extension>::iterator iter = extensions_.find(number);
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+  GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, ENUM);
+  GOOGLE_DCHECK(iter->second.descriptor->enum_type()
+             ->FindValueByNumber(value) != NULL);
+  iter->second.repeated_enum_value->Set(index, value);
+}
+
+void ExtensionSet::AddEnum(int number, int value) {
+  Extension* extension = &extensions_[number];
+  if (extension->descriptor == NULL) {
+    // Not previoulsy present.  Initialize it.
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);
+    GOOGLE_DCHECK_TYPE(descriptor, REPEATED, ENUM);
+    extension->repeated_enum_value = new RepeatedField<int>();
+    extension->descriptor = descriptor;
+  } else {
+    GOOGLE_DCHECK_TYPE(extension->descriptor, REPEATED, ENUM);
+  }
+  GOOGLE_DCHECK(extension->descriptor->enum_type()->FindValueByNumber(value) != NULL);
+  extension->repeated_enum_value->Add(value);
+}
+
+// -------------------------------------------------------------------
+// Strings
+
+const string& ExtensionSet::GetString(int number) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) {
+    // Not present.  Return the default value.
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);
+    GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, STRING);
+    return descriptor->default_value_string();
+  } else {
+    GOOGLE_DCHECK_TYPE(iter->second.descriptor, OPTIONAL, STRING);
+    return *iter->second.string_value;
+  }
+}
+
+string* ExtensionSet::MutableString(int number) {
+  Extension* extension = &extensions_[number];
+  if (extension->descriptor == NULL) {
+    // Not previoulsy present.  Initialize it.
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);
+    GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, STRING);
+    extension->descriptor = descriptor;
+    extension->string_value = new string;
+  } else {
+    GOOGLE_DCHECK_TYPE(extension->descriptor, OPTIONAL, STRING);
+    extension->is_cleared = false;
+  }
+  return extension->string_value;
+}
+
+const string& ExtensionSet::GetRepeatedString(int number, int index) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+  GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, STRING);
+  return iter->second.repeated_string_value->Get(index);
+}
+
+string* ExtensionSet::MutableRepeatedString(int number, int index) {
+  map<int, Extension>::iterator iter = extensions_.find(number);
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+  GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, STRING);
+  return iter->second.repeated_string_value->Mutable(index);
+}
+
+string* ExtensionSet::AddString(int number) {
+  Extension* extension = &extensions_[number];
+  if (extension->descriptor == NULL) {
+    // Not previoulsy present.  Initialize it.
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);
+    GOOGLE_DCHECK_TYPE(descriptor, REPEATED, STRING);
+    extension->repeated_string_value = new RepeatedPtrField<string>();
+    extension->descriptor = descriptor;
+  } else {
+    GOOGLE_DCHECK_TYPE(extension->descriptor, REPEATED, STRING);
+  }
+  return extension->repeated_string_value->Add();
+}
+
+// -------------------------------------------------------------------
+// Messages
+
+const Message& ExtensionSet::GetMessage(int number) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) {
+    // Not present.  Return the default value.
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);
+    GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, MESSAGE);
+    return *GetPrototype(descriptor->message_type());
+  } else {
+    GOOGLE_DCHECK_TYPE(iter->second.descriptor, OPTIONAL, MESSAGE);
+    return *iter->second.message_value;
+  }
+}
+
+Message* ExtensionSet::MutableMessage(int number) {
+  Extension* extension = &extensions_[number];
+  if (extension->descriptor == NULL) {
+    // Not previoulsy present.  Initialize it.
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);
+    GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, MESSAGE);
+    extension->descriptor = descriptor;
+    extension->message_value = GetPrototype(descriptor->message_type())->New();
+  } else {
+    GOOGLE_DCHECK_TYPE(extension->descriptor, OPTIONAL, MESSAGE);
+    extension->is_cleared = false;
+  }
+  return extension->message_value;
+}
+
+const Message& ExtensionSet::GetRepeatedMessage(int number, int index) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+  GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, MESSAGE);
+  return iter->second.repeated_message_value->Get(index);
+}
+
+Message* ExtensionSet::MutableRepeatedMessage(int number, int index) {
+  map<int, Extension>::iterator iter = extensions_.find(number);
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+  GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, MESSAGE);
+  return iter->second.repeated_message_value->Mutable(index);
+}
+
+Message* ExtensionSet::AddMessage(int number) {
+  Extension* extension = &extensions_[number];
+  if (extension->descriptor == NULL) {
+    // Not previoulsy present.  Initialize it.
+    const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number);
+    GOOGLE_DCHECK_TYPE(descriptor, REPEATED, MESSAGE);
+    extension->repeated_message_value =
+      new RepeatedPtrField<Message>(GetPrototype(descriptor->message_type()));
+    extension->descriptor = descriptor;
+  } else {
+    GOOGLE_DCHECK_TYPE(extension->descriptor, REPEATED, MESSAGE);
+  }
+  return extension->repeated_message_value->Add();
+}
+
+#undef GOOGLE_DCHECK_TYPE
+
+// ===================================================================
+
+void ExtensionSet::Clear() {
+  for (map<int, Extension>::iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    iter->second.Clear();
+  }
+}
+
+namespace {
+
+// A helper function for merging RepeatedFields...
+// TODO(kenton):  Implement this as a method of RepeatedField?  Make generated
+//   MergeFrom methods use it?
+
+template <typename Type>
+void MergeRepeatedFields(const RepeatedField<Type>& source,
+                         RepeatedField<Type>* destination) {
+  destination->Reserve(destination->size() + source.size());
+  for (int i = 0; i < source.size(); i++) {
+    destination->Add(source.Get(i));
+  }
+}
+
+void MergeRepeatedFields(const RepeatedPtrField<string>& source,
+                         RepeatedPtrField<string>* destination) {
+  destination->Reserve(destination->size() + source.size());
+  for (int i = 0; i < source.size(); i++) {
+    destination->Add()->assign(source.Get(i));
+  }
+}
+
+void MergeRepeatedFields(const RepeatedPtrField<Message>& source,
+                         RepeatedPtrField<Message>* destination) {
+  destination->Reserve(destination->size() + source.size());
+  for (int i = 0; i < source.size(); i++) {
+    destination->Add()->MergeFrom(source.Get(i));
+  }
+}
+
+}  // namespace
+
+void ExtensionSet::MergeFrom(const ExtensionSet& other) {
+  GOOGLE_DCHECK_EQ(extendee_, other.extendee_);
+
+  for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
+       iter != other.extensions_.end(); ++iter) {
+    const FieldDescriptor* field = iter->second.descriptor;
+    if (field->is_repeated()) {
+      const Extension& other_extension = iter->second;
+      Extension* extension = &extensions_[iter->first];
+      switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE)             \
+        case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
+          if (extension->descriptor == NULL) {                       \
+            extension->descriptor = field;                           \
+            extension->repeated_##LOWERCASE##_value =                \
+              new REPEATED_TYPE;                                     \
+          }                                                          \
+          MergeRepeatedFields(                                       \
+            *other_extension.repeated_##LOWERCASE##_value,           \
+            extension->repeated_##LOWERCASE##_value);                \
+          break;
+
+        HANDLE_TYPE(  INT32,   int32, RepeatedField   <  int32>);
+        HANDLE_TYPE(  INT64,   int64, RepeatedField   <  int64>);
+        HANDLE_TYPE( UINT32,  uint32, RepeatedField   < uint32>);
+        HANDLE_TYPE( UINT64,  uint64, RepeatedField   < uint64>);
+        HANDLE_TYPE(  FLOAT,   float, RepeatedField   <  float>);
+        HANDLE_TYPE( DOUBLE,  double, RepeatedField   < double>);
+        HANDLE_TYPE(   BOOL,    bool, RepeatedField   <   bool>);
+        HANDLE_TYPE(   ENUM,    enum, RepeatedField   <    int>);
+        HANDLE_TYPE( STRING,  string, RepeatedPtrField< string>);
+#undef HANDLE_TYPE
+
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          if (extension->descriptor == NULL) {
+            extension->descriptor = field;
+            extension->repeated_message_value = new RepeatedPtrField<Message>(
+              other_extension.repeated_message_value->prototype());
+          }
+          MergeRepeatedFields(
+            *other_extension.repeated_message_value,
+            extension->repeated_message_value);
+          break;
+      }
+    } else {
+      if (!iter->second.is_cleared) {
+        switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE)                       \
+          case FieldDescriptor::CPPTYPE_##UPPERCASE:                       \
+            Set##CAMELCASE(iter->first, iter->second.LOWERCASE##_value);   \
+            break;
+
+          HANDLE_TYPE( INT32,  int32,  Int32);
+          HANDLE_TYPE( INT64,  int64,  Int64);
+          HANDLE_TYPE(UINT32, uint32, UInt32);
+          HANDLE_TYPE(UINT64, uint64, UInt64);
+          HANDLE_TYPE( FLOAT,  float,  Float);
+          HANDLE_TYPE(DOUBLE, double, Double);
+          HANDLE_TYPE(  BOOL,   bool,   Bool);
+          HANDLE_TYPE(  ENUM,   enum,   Enum);
+#undef HANDLE_TYPE
+          case FieldDescriptor::CPPTYPE_STRING:
+            SetString(iter->first, *iter->second.string_value);
+            break;
+          case FieldDescriptor::CPPTYPE_MESSAGE:
+            MutableMessage(iter->first)->MergeFrom(*iter->second.message_value);
+            break;
+        }
+      }
+    }
+  }
+}
+
+bool ExtensionSet::IsInitialized() const {
+  // Extensions are never requried.  However, we need to check that all
+  // embedded messages are initialized.
+  for (map<int, Extension>::const_iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    const Extension& extension = iter->second;
+    if (extension.descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (extension.descriptor->is_repeated()) {
+        for (int i = 0; i < extension.repeated_message_value->size(); i++) {
+          if (!extension.repeated_message_value->Get(i).IsInitialized()) {
+            return false;
+          }
+        }
+      } else {
+        if (!extension.is_cleared) {
+          if (!extension.message_value->IsInitialized()) return false;
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+                              Message::Reflection* reflection) {
+  const FieldDescriptor* field =
+    FindKnownExtensionByNumber(WireFormat::GetTagFieldNumber(tag));
+
+  return WireFormat::ParseAndMergeField(tag, field, reflection, input);
+}
+
+bool ExtensionSet::SerializeWithCachedSizes(
+    int start_field_number, int end_field_number,
+    const Message::Reflection* reflection,
+    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)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+int ExtensionSet::ByteSize(const Message::Reflection* reflection) const {
+  int total_size = 0;
+
+  for (map<int, Extension>::const_iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    total_size += iter->second.ByteSize(reflection);
+  }
+
+  return total_size;
+}
+
+// ===================================================================
+// Methods of ExtensionSet::Extension
+
+void ExtensionSet::Extension::Clear() {
+  if (descriptor->is_repeated()) {
+    switch (descriptor->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
+      case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
+        repeated_##LOWERCASE##_value->Clear();                     \
+        break
+
+      HANDLE_TYPE(  INT32,   int32);
+      HANDLE_TYPE(  INT64,   int64);
+      HANDLE_TYPE( UINT32,  uint32);
+      HANDLE_TYPE( UINT64,  uint64);
+      HANDLE_TYPE(  FLOAT,   float);
+      HANDLE_TYPE( DOUBLE,  double);
+      HANDLE_TYPE(   BOOL,    bool);
+      HANDLE_TYPE(   ENUM,    enum);
+      HANDLE_TYPE( STRING,  string);
+      HANDLE_TYPE(MESSAGE, message);
+#undef HANDLE_TYPE
+    }
+  } else {
+    if (!is_cleared) {
+      switch (descriptor->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                 \
+        case FieldDescriptor::CPPTYPE_##UPPERCASE:                        \
+          LOWERCASE##_value = descriptor->default_value_##LOWERCASE();    \
+          break
+
+        HANDLE_TYPE( INT32,  int32);
+        HANDLE_TYPE( INT64,  int64);
+        HANDLE_TYPE(UINT32, uint32);
+        HANDLE_TYPE(UINT64, uint64);
+        HANDLE_TYPE( FLOAT,  float);
+        HANDLE_TYPE(DOUBLE, double);
+        HANDLE_TYPE(  BOOL,   bool);
+#undef HANDLE_TYPE
+        case FieldDescriptor::CPPTYPE_ENUM:
+          enum_value = descriptor->default_value_enum()->number();
+          break;
+        case FieldDescriptor::CPPTYPE_STRING:
+          if (descriptor->has_default_value()) {
+            string_value->assign(descriptor->default_value_string());
+          } else {
+            string_value->clear();
+          }
+          break;
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          message_value->Clear();
+          break;
+      }
+
+      is_cleared = true;
+    }
+  }
+}
+
+bool ExtensionSet::Extension::SerializeFieldWithCachedSizes(
+    const Message::Reflection* reflection,
+    io::CodedOutputStream* output) const {
+  if (descriptor->is_repeated() || !is_cleared) {
+    return WireFormat::SerializeFieldWithCachedSizes(
+        descriptor, reflection, output);
+  } else {
+    return true;
+  }
+}
+
+int64 ExtensionSet::Extension::ByteSize(
+    const Message::Reflection* reflection) const {
+  if (descriptor->is_repeated() || !is_cleared) {
+    return WireFormat::FieldByteSize(descriptor, reflection);
+  } else {
+    // Cleared, non-repeated field.
+    return 0;
+  }
+}
+
+int ExtensionSet::Extension::GetSize() const {
+  GOOGLE_DCHECK(descriptor->is_repeated());
+  switch (descriptor->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                        \
+    case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
+      return repeated_##LOWERCASE##_value->size()
+
+    HANDLE_TYPE(  INT32,   int32);
+    HANDLE_TYPE(  INT64,   int64);
+    HANDLE_TYPE( UINT32,  uint32);
+    HANDLE_TYPE( UINT64,  uint64);
+    HANDLE_TYPE(  FLOAT,   float);
+    HANDLE_TYPE( DOUBLE,  double);
+    HANDLE_TYPE(   BOOL,    bool);
+    HANDLE_TYPE(   ENUM,    enum);
+    HANDLE_TYPE( STRING,  string);
+    HANDLE_TYPE(MESSAGE, message);
+#undef HANDLE_TYPE
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return 0;
+}
+
+void ExtensionSet::Extension::Free() {
+  if (descriptor->is_repeated()) {
+    switch (descriptor->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
+      case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
+        delete repeated_##LOWERCASE##_value;                       \
+        break
+
+      HANDLE_TYPE(  INT32,   int32);
+      HANDLE_TYPE(  INT64,   int64);
+      HANDLE_TYPE( UINT32,  uint32);
+      HANDLE_TYPE( UINT64,  uint64);
+      HANDLE_TYPE(  FLOAT,   float);
+      HANDLE_TYPE( DOUBLE,  double);
+      HANDLE_TYPE(   BOOL,    bool);
+      HANDLE_TYPE(   ENUM,    enum);
+      HANDLE_TYPE( STRING,  string);
+      HANDLE_TYPE(MESSAGE, message);
+#undef HANDLE_TYPE
+    }
+  } else {
+    switch (descriptor->cpp_type()) {
+      case FieldDescriptor::CPPTYPE_STRING:
+        delete string_value;
+        break;
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        delete message_value;
+        break;
+      default:
+        break;
+    }
+  }
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
new file mode 100644
index 0000000..902ec73
--- /dev/null
+++ b/src/google/protobuf/extension_set.h
@@ -0,0 +1,555 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__
+#define GOOGLE_PROTOBUF_EXTENSION_SET_H__
+
+#include <vector>
+#include <stack>
+#include <map>
+#include <utility>
+#include <string>
+
+#include <google/protobuf/message.h>
+
+namespace google {
+namespace protobuf {
+  class Descriptor;                                    // descriptor.h
+  class FieldDescriptor;                               // descriptor.h
+  class DescriptorPool;                                // descriptor.h
+  class Message;                                       // message.h
+  class MessageFactory;                                // message.h
+  namespace io {
+    class CodedInputStream;                              // coded_stream.h
+    class CodedOutputStream;                             // coded_stream.h
+  }
+  template <typename Element> class RepeatedField;     // repeated_field.h
+  template <typename Element> class RepeatedPtrField;  // repeated_field.h
+}
+
+namespace protobuf {
+namespace internal {
+
+// This is an internal helper class intended for use within the protocol buffer
+// library and generated classes.  Clients should not use it directly.  Instead,
+// use the generated accessors such as GetExtension() of the class being
+// extended.
+//
+// This class manages extensions for a protocol message object.  The
+// message's HasExtension(), GetExtension(), MutableExtension(), and
+// ClearExtension() methods are just thin wrappers around the embedded
+// ExtensionSet.  When parsing, if a tag number is encountered which is
+// inside one of the message type's extension ranges, the tag is passed
+// off to the ExtensionSet for parsing.  Etc.
+class LIBPROTOBUF_EXPORT ExtensionSet {
+ public:
+  // Construct an ExtensionSet.
+  //   extendee:  Descriptor for the type being extended.
+  //   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,
+               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().
+  void AppendToList(vector<const FieldDescriptor*>* output) const;
+
+  // =================================================================
+  // Accessors
+  //
+  // Generated message classes include type-safe templated wrappers around
+  // these methods.  Generally you should use those rather than call these
+  // directly, unless you are doing low-level memory management.
+  //
+  // When calling any of these accessors, the extension number requested
+  // MUST exist in the DescriptorPool provided to the constructor.  Otheriwse,
+  // the method will fail an assert.  Normally, though, you would not call
+  // these directly; you would either call the generated accessors of your
+  // message class (e.g. GetExtension()) or you would call the accessors
+  // of the reflection interface.  In both cases, it is impossible to
+  // trigger this assert failure:  the generated accessors only accept
+  // linked-in extension types as parameters, while the Reflection interface
+  // requires you to provide the FieldDescriptor describing the extension.
+  //
+  // When calling any of these accessors, a protocol-compiler-generated
+  // implementation of the extension corresponding to the number MUST
+  // be linked in, and the FieldDescriptor used to refer to it MUST be
+  // the one generated by that linked-in code.  Otherwise, the method will
+  // 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:
+  // - They're not virtual.
+  // - They identify fields by number rather than FieldDescriptors.
+  // - They identify enum values using integers rather than descriptors.
+  // - Strings provide Mutable() in addition to Set() accessors.
+
+  bool Has(int number) const;
+  int ExtensionSize(int number) const;   // Size of a repeated extension.
+  void ClearExtension(int number);
+
+  // singular fields -------------------------------------------------
+
+  int32  GetInt32 (int number) const;
+  int64  GetInt64 (int number) const;
+  uint32 GetUInt32(int number) const;
+  uint64 GetUInt64(int number) const;
+  float  GetFloat (int number) const;
+  double GetDouble(int number) const;
+  bool   GetBool  (int number) const;
+  int    GetEnum  (int number) const;
+  const string & GetString (int number) const;
+  const Message& GetMessage(int number) const;
+
+  void SetInt32 (int number, int32  value);
+  void SetInt64 (int number, int64  value);
+  void SetUInt32(int number, uint32 value);
+  void SetUInt64(int number, uint64 value);
+  void SetFloat (int number, float  value);
+  void SetDouble(int number, double value);
+  void SetBool  (int number, bool   value);
+  void SetEnum  (int number, int    value);
+  void SetString(int number, const string& value);
+  string * MutableString (int number);
+  Message* MutableMessage(int number);
+
+  // repeated fields -------------------------------------------------
+
+  int32  GetRepeatedInt32 (int number, int index) const;
+  int64  GetRepeatedInt64 (int number, int index) const;
+  uint32 GetRepeatedUInt32(int number, int index) const;
+  uint64 GetRepeatedUInt64(int number, int index) const;
+  float  GetRepeatedFloat (int number, int index) const;
+  double GetRepeatedDouble(int number, int index) const;
+  bool   GetRepeatedBool  (int number, int index) const;
+  int    GetRepeatedEnum  (int number, int index) const;
+  const string & GetRepeatedString (int number, int index) const;
+  const Message& GetRepeatedMessage(int number, int index) const;
+
+  void SetRepeatedInt32 (int number, int index, int32  value);
+  void SetRepeatedInt64 (int number, int index, int64  value);
+  void SetRepeatedUInt32(int number, int index, uint32 value);
+  void SetRepeatedUInt64(int number, int index, uint64 value);
+  void SetRepeatedFloat (int number, int index, float  value);
+  void SetRepeatedDouble(int number, int index, double value);
+  void SetRepeatedBool  (int number, int index, bool   value);
+  void SetRepeatedEnum  (int number, int index, int    value);
+  void SetRepeatedString(int number, int index, const string& value);
+  string * MutableRepeatedString (int number, int index);
+  Message* MutableRepeatedMessage(int number, int index);
+
+  void AddInt32 (int number, int32  value);
+  void AddInt64 (int number, int64  value);
+  void AddUInt32(int number, uint32 value);
+  void AddUInt64(int number, uint64 value);
+  void AddFloat (int number, float  value);
+  void AddDouble(int number, double value);
+  void AddBool  (int number, bool   value);
+  void AddEnum  (int number, int    value);
+  void AddString(int number, const string& value);
+  string * AddString (int number);
+  Message* AddMessage(int number);
+
+  // -----------------------------------------------------------------
+  // TODO(kenton):  Hardcore memory management accessors
+
+  // =================================================================
+  // convenience methods for implementing methods of Message
+  //
+  // These could all be implemented in terms of the other methods of this
+  // class, but providing them here helps keep the generated code size down.
+
+  void Clear();
+  void MergeFrom(const ExtensionSet& other);
+  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,
+  // 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
+  // involve reproducing a lot of WireFormat's functionality.
+
+  // 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);
+
+  // Write all extension fields with field numbers in the range
+  //   [start_field_number, end_field_number)
+  // to the output stream, using the cached sizes computed when ByteSize() was
+  // last called.  Note that the range bounds are inclusive-exclusive.
+  bool SerializeWithCachedSizes(int start_field_number,
+                                int end_field_number,
+                                const Message::Reflection* reflection,
+                                io::CodedOutputStream* output) const;
+
+  // Returns the total serialized size of all the extensions.
+  int ByteSize(const Message::Reflection* reflection) const;
+
+ private:
+  // Like FindKnownExtension(), but GOOGLE_CHECK-fail if not found.
+  const FieldDescriptor* FindKnownExtensionOrDie(int number) const;
+
+  // Get the prototype for the message.
+  const Message* GetPrototype(const Descriptor* message_type) const;
+
+  struct Extension {
+    union {
+      int32    int32_value;
+      int64    int64_value;
+      uint32   uint32_value;
+      uint64   uint64_value;
+      float    float_value;
+      double   double_value;
+      bool     bool_value;
+      int      enum_value;
+      string*  string_value;
+      Message* message_value;
+
+      RepeatedField   <int32  >* repeated_int32_value;
+      RepeatedField   <int64  >* repeated_int64_value;
+      RepeatedField   <uint32 >* repeated_uint32_value;
+      RepeatedField   <uint64 >* repeated_uint64_value;
+      RepeatedField   <float  >* repeated_float_value;
+      RepeatedField   <double >* repeated_double_value;
+      RepeatedField   <bool   >* repeated_bool_value;
+      RepeatedField   <int    >* repeated_enum_value;
+      RepeatedPtrField<string >* repeated_string_value;
+      RepeatedPtrField<Message>* repeated_message_value;
+    };
+
+    const FieldDescriptor* descriptor;
+
+    // For singular types, indicates if the extension is "cleared".  This
+    // happens when an extension is set and then later cleared by the caller.
+    // We want to keep the Extension object around for reuse, so instead of
+    // removing it from the map, we just set is_cleared = true.  This has no
+    // meaning for repeated types; for those, the size of the RepeatedField
+    // simply becomes zero when cleared.
+    bool is_cleared;
+
+    Extension(): descriptor(NULL), is_cleared(false) {}
+
+    // Some helper methods for operations on a single Extension.
+    bool SerializeFieldWithCachedSizes(
+        const Message::Reflection* reflection,
+        io::CodedOutputStream* output) const;
+    int64 ByteSize(const Message::Reflection* reflection) const;
+    void Clear();
+    int GetSize() const;
+    void Free();
+  };
+
+  // The Extension struct is small enough to be passed by value, so we use it
+  // directly as the value type in the map rather than use pointers.  We use
+  // a map rather than hash_map here because we expect most ExtensionSets will
+  // only contain a small number of extensions whereas hash_map is optimized
+  // for 100 elements or more.  Also, we want AppendToList() to order fields
+  // by field number.
+  map<int, Extension> extensions_;
+  const Descriptor* extendee_;
+  const DescriptorPool* descriptor_pool_;
+  MessageFactory* message_factory_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
+};
+
+// These are just for convenience...
+inline void ExtensionSet::SetString(int number, const string& value) {
+  MutableString(number)->assign(value);
+}
+inline void ExtensionSet::SetRepeatedString(int number, int index,
+                                            const string& value) {
+  MutableRepeatedString(number, index)->assign(value);
+}
+inline void ExtensionSet::AddString(int number, const string& value) {
+  AddString(number)->assign(value);
+}
+
+// ===================================================================
+// Implementation details
+//
+// DO NOT DEPEND ON ANYTHING BELOW THIS POINT.  This is for use from
+// generated code only.
+
+// -------------------------------------------------------------------
+// Template magic
+
+// First we have a set of classes representing "type traits" for different
+// field types.  A type traits class knows how to implement basic accessors
+// for extensions of a particular type given an ExtensionSet.  The signature
+// for a type traits class looks like this:
+//
+//   class TypeTraits {
+//    public:
+//     typedef ? ConstType;
+//     typedef ? MutableType;
+//
+//     static inline ConstType Get(int number, const ExtensionSet& set);
+//     static inline void Set(int number, ConstType value, ExtensionSet* set);
+//     static inline MutableType Mutable(int number, ExtensionSet* set);
+//
+//     // Variants for repeated fields.
+//     static inline ConstType Get(int number, const ExtensionSet& set,
+//                                 int index);
+//     static inline void Set(int number, int index,
+//                            ConstType value, ExtensionSet* set);
+//     static inline MutableType Mutable(int number, int index,
+//                                       ExtensionSet* set);
+//     static inline void Add(int number, ConstType value, ExtensionSet* set);
+//     static inline MutableType Add(int number, ExtensionSet* set);
+//   };
+//
+// Not all of these methods make sense for all field types.  For example, the
+// "Mutable" methods only make sense for strings and messages, and the
+// repeated methods only make sense for repeated types.  So, each type
+// traits class implements only the set of methods from this signature that it
+// actually supports.  This will cause a compiler error if the user tries to
+// access an extension using a method that doesn't make sense for its type.
+// For example, if "foo" is an extension of type "optional int32", then if you
+// try to write code like:
+//   my_message.MutableExtension(foo)
+// you will get a compile error because PrimitiveTypeTraits<int32> does not
+// have a "Mutable()" method.
+
+// -------------------------------------------------------------------
+// PrimitiveTypeTraits
+
+// Since the ExtensionSet has different methods for each primitive type,
+// we must explicitly define the methods of the type traits class for each
+// known type.
+template <typename Type>
+class PrimitiveTypeTraits {
+ public:
+  typedef Type ConstType;
+
+  static inline ConstType Get(int number, const ExtensionSet& set);
+  static inline void Set(int number, ConstType value, ExtensionSet* set);
+};
+
+template <typename Type>
+class RepeatedPrimitiveTypeTraits {
+ public:
+  typedef Type ConstType;
+
+  static inline Type Get(int number, const ExtensionSet& set, int index);
+  static inline void Set(int number, int index, Type value, ExtensionSet* set);
+  static inline void Add(int number, Type value, ExtensionSet* set);
+};
+
+#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD)                       \
+template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get(                     \
+    int number, const ExtensionSet& set) {                                 \
+  return set.Get##METHOD(number);                                          \
+}                                                                          \
+template<> inline void PrimitiveTypeTraits<TYPE>::Set(                     \
+    int number, ConstType value, ExtensionSet* set) {                      \
+  set->Set##METHOD(number, value);                                         \
+}                                                                          \
+                                                                           \
+template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get(             \
+    int number, const ExtensionSet& set, int index) {                      \
+  return set.GetRepeated##METHOD(number, index);                           \
+}                                                                          \
+template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set(             \
+    int number, int index, ConstType value, ExtensionSet* set) {           \
+  set->SetRepeated##METHOD(number, index, value);                          \
+}                                                                          \
+template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add(             \
+    int number, ConstType value, ExtensionSet* set) {                      \
+  set->Add##METHOD(number, value);                                         \
+}
+
+PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32,  Int32)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64,  Int64)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE( float,  Float)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(  bool,   Bool)
+
+#undef PROTOBUF_DEFINE_PRIMITIVE_TYPE
+
+// -------------------------------------------------------------------
+// StringTypeTraits
+
+// Strings support both Set() and Mutable().
+class LIBPROTOBUF_EXPORT StringTypeTraits {
+ public:
+  typedef const string& ConstType;
+  typedef string* MutableType;
+
+  static inline const string& Get(int number, const ExtensionSet& set) {
+    return set.GetString(number);
+  }
+  static inline void Set(int number, const string& value, ExtensionSet* set) {
+    set->SetString(number, value);
+  }
+  static inline string* Mutable(int number, ExtensionSet* set) {
+    return set->MutableString(number);
+  }
+};
+
+class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
+ public:
+  typedef const string& ConstType;
+  typedef string* MutableType;
+
+  static inline const string& Get(int number, const ExtensionSet& set,
+                                  int index) {
+    return set.GetRepeatedString(number, index);
+  }
+  static inline void Set(int number, int index,
+                         const string& value, ExtensionSet* set) {
+    set->SetRepeatedString(number, index, value);
+  }
+  static inline string* Mutable(int number, int index, ExtensionSet* set) {
+    return set->MutableRepeatedString(number, index);
+  }
+  static inline void Add(int number, const string& value, ExtensionSet* set) {
+    set->AddString(number, value);
+  }
+  static inline string* Add(int number, ExtensionSet* set) {
+    return set->AddString(number);
+  }
+};
+
+// -------------------------------------------------------------------
+// EnumTypeTraits
+
+// ExtensionSet represents enums using integers internally, so we have to
+// static_cast around.
+template <typename Type>
+class EnumTypeTraits {
+ public:
+  typedef Type ConstType;
+
+  static inline ConstType Get(int number, const ExtensionSet& set) {
+    return static_cast<Type>(set.GetEnum(number));
+  }
+  static inline void Set(int number, ConstType value, ExtensionSet* set) {
+    set->SetEnum(number, value);
+  }
+};
+
+template <typename Type>
+class RepeatedEnumTypeTraits {
+ public:
+  typedef Type ConstType;
+
+  static inline ConstType Get(int number, const ExtensionSet& set, int index) {
+    return static_cast<Type>(set.GetRepeatedEnum(number, index));
+  }
+  static inline void Set(int number, int index,
+                         ConstType value, ExtensionSet* set) {
+    set->SetRepeatedEnum(number, index, value);
+  }
+  static inline void Add(int number, ConstType value, ExtensionSet* set) {
+    set->AddEnum(number, value);
+  }
+};
+
+// -------------------------------------------------------------------
+// MessageTypeTraits
+
+// ExtensionSet guarantees that when manipulating extensions with message
+// types, the implementation used will be the compiled-in class representing
+// that type.  So, we can static_cast down to the exact type we expect.
+template <typename Type>
+class MessageTypeTraits {
+ public:
+  typedef const Type& ConstType;
+ typedef Type* MutableType;
+
+  static inline ConstType Get(int number, const ExtensionSet& set) {
+    return static_cast<const Type&>(set.GetMessage(number));
+  }
+  static inline MutableType Mutable(int number, ExtensionSet* set) {
+    return static_cast<Type*>(set->MutableMessage(number));
+  }
+};
+
+template <typename Type>
+class RepeatedMessageTypeTraits {
+ public:
+  typedef const Type& ConstType;
+  typedef Type* MutableType;
+
+  static inline ConstType Get(int number, const ExtensionSet& set, int index) {
+    return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
+  }
+  static inline MutableType Mutable(int number, int index, ExtensionSet* set) {
+    return static_cast<Type*>(set->MutableRepeatedMessage(number, index));
+  }
+  static inline MutableType Add(int number, ExtensionSet* set) {
+    return static_cast<Type*>(set->AddMessage(number));
+  }
+};
+
+// -------------------------------------------------------------------
+// ExtensionIdentifier
+
+// This is the type of actual extension objects.  E.g. if you have:
+//   extends Foo with optional int32 bar = 1234;
+// then "bar" will be defined in C++ as:
+//   ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32>> bar(1234);
+//
+// Note that we could, in theory, supply the field number as a template
+// parameter, and thus make an instance of ExtensionIdentifier have no
+// actual contents.  However, if we did that, then using at extension
+// identifier would not necessarily cause the compiler to output any sort
+// of reference to any simple defined in the extension's .pb.o file.  Some
+// linkers will actually drop object files that are not explicitly referenced,
+// but that would be bad because it would cause this extension to not be
+// registered at static initialization, and therefore using it would crash.
+
+template <typename ExtendeeType, typename TypeTraitsType>
+class ExtensionIdentifier {
+ public:
+  typedef TypeTraitsType TypeTraits;
+  typedef ExtendeeType Extendee;
+
+  ExtensionIdentifier(int number): number_(number) {}
+  inline int number() const { return number_; }
+ private:
+  const int number_;
+};
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_EXTENSION_SET_H__
diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc
new file mode 100644
index 0000000..c10f890
--- /dev/null
+++ b/src/google/protobuf/extension_set_unittest.cc
@@ -0,0 +1,195 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+// This test closely mirrors google/protobuf/compiler/cpp/unittest.cc
+// except that it uses extensions rather than regular fields.
+
+TEST(ExtensionSetTest, Defaults) {
+  // Check that all default values are set correctly in the initial message.
+  unittest::TestAllExtensions message;
+
+  TestUtil::ExpectExtensionsClear(message);
+
+  // 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::OptionalGroup_extension::default_instance(),
+            &message.GetExtension(unittest::optionalgroup_extension));
+  EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &message.GetExtension(unittest::optional_nested_message_extension));
+  EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
+            &message.GetExtension(
+              unittest::optional_foreign_message_extension));
+  EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
+            &message.GetExtension(unittest::optional_import_message_extension));
+}
+
+TEST(ExtensionSetTest, Accessors) {
+  // Set every field to a unique value then go back and check all those
+  // values.
+  unittest::TestAllExtensions message;
+
+  TestUtil::SetAllExtensions(&message);
+  TestUtil::ExpectAllExtensionsSet(message);
+
+  TestUtil::ModifyRepeatedExtensions(&message);
+  TestUtil::ExpectRepeatedExtensionsModified(message);
+}
+
+TEST(ExtensionSetTest, Clear) {
+  // Set every field to a unique value, clear the message, then check that
+  // it is cleared.
+  unittest::TestAllExtensions message;
+
+  TestUtil::SetAllExtensions(&message);
+  message.Clear();
+  TestUtil::ExpectExtensionsClear(message);
+
+  // Unlike with the defaults test, we do NOT expect that requesting embedded
+  // messages will return a pointer to the default instance.  Instead, they
+  // should return the objects that were created when mutable_blah() was
+  // called.
+  EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
+            &message.GetExtension(unittest::optionalgroup_extension));
+  EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &message.GetExtension(unittest::optional_nested_message_extension));
+  EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+            &message.GetExtension(
+              unittest::optional_foreign_message_extension));
+  EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+            &message.GetExtension(unittest::optional_import_message_extension));
+}
+
+TEST(ExtensionSetTest, ClearOneField) {
+  // Set every field to a unique value, then clear one value and insure that
+  // only that one value is cleared.
+  unittest::TestAllExtensions message;
+
+  TestUtil::SetAllExtensions(&message);
+  int64 original_value =
+    message.GetExtension(unittest::optional_int64_extension);
+
+  // Clear the field and make sure it shows up as cleared.
+  message.ClearExtension(unittest::optional_int64_extension);
+  EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension));
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension));
+
+  // Other adjacent fields should not be cleared.
+  EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension));
+
+  // Make sure if we set it again, then all fields are set.
+  message.SetExtension(unittest::optional_int64_extension, original_value);
+  TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ExtensionSetTest, CopyFrom) {
+  unittest::TestAllExtensions message1, message2;
+  string data;
+
+  TestUtil::SetAllExtensions(&message1);
+  message2.CopyFrom(message1);
+  TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, Serialization) {
+  // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
+  // compatibility of extensions.
+  unittest::TestAllExtensions source;
+  unittest::TestAllTypes destination;
+  string data;
+
+  TestUtil::SetAllExtensions(&source);
+  source.SerializeToString(&data);
+  EXPECT_TRUE(destination.ParseFromString(data));
+  TestUtil::ExpectAllFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, Parsing) {
+  // Serialize as TestAllTypes and parse as TestAllExtensions.
+  unittest::TestAllTypes source;
+  unittest::TestAllExtensions destination;
+  string data;
+
+  TestUtil::SetAllFields(&source);
+  source.SerializeToString(&data);
+  EXPECT_TRUE(destination.ParseFromString(data));
+  TestUtil::ExpectAllExtensionsSet(destination);
+}
+
+TEST(ExtensionSetTest, IsInitialized) {
+  // Test that IsInitialized() returns false if required fields in nested
+  // extensions are missing.
+  unittest::TestAllExtensions message;
+
+  EXPECT_TRUE(message.IsInitialized());
+
+  message.MutableExtension(unittest::TestRequired::single);
+  EXPECT_FALSE(message.IsInitialized());
+
+  message.MutableExtension(unittest::TestRequired::single)->set_a(1);
+  EXPECT_FALSE(message.IsInitialized());
+  message.MutableExtension(unittest::TestRequired::single)->set_b(2);
+  EXPECT_FALSE(message.IsInitialized());
+  message.MutableExtension(unittest::TestRequired::single)->set_c(3);
+  EXPECT_TRUE(message.IsInitialized());
+
+  message.AddExtension(unittest::TestRequired::multi);
+  EXPECT_FALSE(message.IsInitialized());
+
+  message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
+  EXPECT_FALSE(message.IsInitialized());
+  message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
+  EXPECT_FALSE(message.IsInitialized());
+  message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
+  EXPECT_TRUE(message.IsInitialized());
+}
+
+TEST(ExtensionSetTest, MutableString) {
+  // Test the mutable string accessors.
+  unittest::TestAllExtensions message;
+
+  message.MutableExtension(unittest::optional_string_extension)->assign("foo");
+  EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension));
+  EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension));
+
+  message.AddExtension(unittest::repeated_string_extension)->assign("bar");
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension));
+  EXPECT_EQ("bar",
+            message.GetExtension(unittest::repeated_string_extension, 0));
+}
+
+}  // namespace
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
new file mode 100644
index 0000000..ec17572
--- /dev/null
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -0,0 +1,665 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <algorithm>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+namespace { const string kEmptyString; }
+
+// ===================================================================
+// Helpers for reporting usage errors (e.g. trying to use GetInt32() on
+// a string field).
+
+namespace {
+
+void ReportReflectionUsageError(
+    const Descriptor* descriptor, const FieldDescriptor* field,
+    const char* method, const char* description) {
+  GOOGLE_LOG(FATAL)
+    << "Protocol Buffer reflection usage error:\n"
+       "  Method      : google::protobuf::Message::Reflection::" << method << "\n"
+       "  Message type: " << descriptor->full_name() << "\n"
+       "  Field       : " << field->full_name() << "\n"
+       "  Problem     : " << description;
+}
+
+const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
+  "INVALID_CPPTYPE",
+  "CPPTYPE_INT32",
+  "CPPTYPE_INT64",
+  "CPPTYPE_UINT32",
+  "CPPTYPE_UINT64",
+  "CPPTYPE_DOUBLE",
+  "CPPTYPE_FLOAT",
+  "CPPTYPE_BOOL",
+  "CPPTYPE_ENUM",
+  "CPPTYPE_STRING",
+  "CPPTYPE_MESSAGE"
+};
+
+static void ReportReflectionUsageTypeError(
+    const Descriptor* descriptor, const FieldDescriptor* field,
+    const char* method,
+    FieldDescriptor::CppType expected_type) {
+  GOOGLE_LOG(FATAL)
+    << "Protocol Buffer reflection usage error:\n"
+       "  Method      : google::protobuf::Message::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"
+       "    Expected  : " << cpptype_names_[expected_type] << "\n"
+       "    Field type: " << cpptype_names_[field->cpp_type()];
+}
+
+static void ReportReflectionUsageEnumTypeError(
+    const Descriptor* descriptor, const FieldDescriptor* field,
+    const char* method, const EnumValueDescriptor* value) {
+  GOOGLE_LOG(FATAL)
+    << "Protocol Buffer reflection usage error:\n"
+       "  Method      : google::protobuf::Message::Reflection::" << method << "\n"
+       "  Message type: " << descriptor->full_name() << "\n"
+       "  Field       : " << field->full_name() << "\n"
+       "  Problem     : Enum value did not match field type:\n"
+       "    Expected  : " << field->enum_type()->full_name() << "\n"
+       "    Actual    : " << value->full_name();
+}
+
+#define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION)                      \
+  if (!(CONDITION))                                                            \
+    ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
+#define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION)                        \
+  USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
+#define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION)                        \
+  USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
+
+#define USAGE_CHECK_TYPE(METHOD, CPPTYPE)                                      \
+  if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE)                 \
+    ReportReflectionUsageTypeError(descriptor_, field, #METHOD,                \
+                                   FieldDescriptor::CPPTYPE_##CPPTYPE)
+
+#define USAGE_CHECK_ENUM_VALUE(METHOD)                                         \
+  if (value->type() != field->enum_type())                                     \
+    ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
+
+#define USAGE_CHECK_MESSAGE_TYPE(METHOD)                                       \
+  USAGE_CHECK_EQ(field->containing_type(), descriptor_,                        \
+                 METHOD, "Field does not match message type.");
+#define USAGE_CHECK_SINGULAR(METHOD)                                           \
+  USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD,      \
+                 "Field is repeated; the method requires a singular field.")
+#define USAGE_CHECK_REPEATED(METHOD)                                           \
+  USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD,      \
+                 "Field is singular; the method requires a repeated field.")
+
+#define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE)                       \
+    USAGE_CHECK_MESSAGE_TYPE(METHOD);                                 \
+    USAGE_CHECK_##LABEL(METHOD);                                      \
+    USAGE_CHECK_TYPE(METHOD, CPPTYPE)
+
+}  // namespace
+
+// ===================================================================
+
+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) {
+}
+
+GeneratedMessageReflection::~GeneratedMessageReflection() {}
+
+const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields() const {
+  return unknown_fields_;
+}
+UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields() {
+  return &unknown_fields_;
+}
+
+// -------------------------------------------------------------------
+
+bool GeneratedMessageReflection::HasField(const FieldDescriptor* field) const {
+  USAGE_CHECK_MESSAGE_TYPE(HasField);
+  USAGE_CHECK_SINGULAR(HasField);
+
+  if (field->is_extension()) {
+    return extensions_->Has(field->number());
+  } else {
+    return HasBit(field);
+  }
+}
+
+int GeneratedMessageReflection::FieldSize(const FieldDescriptor* field) const {
+  USAGE_CHECK_MESSAGE_TYPE(HasField);
+  USAGE_CHECK_REPEATED(HasField);
+
+  if (field->is_extension()) {
+    return extensions_->ExtensionSize(field->number());
+  } else {
+    return GetRaw<GenericRepeatedField>(field).GenericSize();
+  }
+}
+
+void GeneratedMessageReflection::ClearField(const FieldDescriptor* field) {
+  USAGE_CHECK_MESSAGE_TYPE(ClearField);
+
+  if (field->is_extension()) {
+    extensions_->ClearExtension(field->number());
+  } else if (!field->is_repeated()) {
+    if (HasBit(field)) {
+      ClearBit(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();          \
+          break;
+
+        CLEAR_TYPE(INT32 , int32 );
+        CLEAR_TYPE(INT64 , int64 );
+        CLEAR_TYPE(UINT32, uint32);
+        CLEAR_TYPE(UINT64, uint64);
+        CLEAR_TYPE(FLOAT , float );
+        CLEAR_TYPE(DOUBLE, double);
+        CLEAR_TYPE(BOOL  , bool  );
+#undef CLEAR_TYPE
+
+        case FieldDescriptor::CPPTYPE_ENUM:
+          *MutableRaw<int>(field) = field->default_value_enum()->number();
+          break;
+
+        case FieldDescriptor::CPPTYPE_STRING: {
+            const string* default_ptr = DefaultRaw<const string*>(field);
+            string** value = MutableRaw<string*>(field);
+            if (*value != default_ptr) {
+              if (field->has_default_value()) {
+                (*value)->assign(field->default_value_string());
+              } else {
+                (*value)->clear();
+              }
+            }
+          break;
+        }
+
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          (*MutableRaw<Message*>(field))->Clear();
+          break;
+      }
+    }
+  } else {
+    MutableRaw<GenericRepeatedField>(field)->GenericClear();
+  }
+}
+
+namespace {
+// Comparison functor for sorting FieldDescriptors by field number.
+struct FieldNumberSorter {
+  bool operator()(const FieldDescriptor* left,
+                  const FieldDescriptor* right) const {
+    return left->number() < right->number();
+  }
+};
+}  // namespace
+
+void GeneratedMessageReflection::ListFields(
+    vector<const FieldDescriptor*>* output) const {
+  output->clear();
+
+  // Optimization:  The default instance never has any fields set.
+  if (base_ == default_base_) 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) {
+        output->push_back(field);
+      }
+    } else {
+      if (HasBit(field)) {
+        output->push_back(field);
+      }
+    }
+  }
+
+  if (extensions_ != NULL) {
+    extensions_->AppendToList(output);
+  }
+
+  // ListFields() must sort output by field number.
+  sort(output->begin(), output->end(), FieldNumberSorter());
+}
+
+// -------------------------------------------------------------------
+
+#undef DEFINE_PRIMITIVE_ACCESSORS
+#define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE)        \
+  PASSTYPE GeneratedMessageReflection::Get##TYPENAME(                        \
+                                       const FieldDescriptor* field) const { \
+    USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE);                       \
+    if (field->is_extension()) {                                             \
+      return extensions_->Get##TYPENAME(field->number());                    \
+    } else {                                                                 \
+      return GetField<TYPE>(field);                                          \
+    }                                                                        \
+  }                                                                          \
+                                                                             \
+  void GeneratedMessageReflection::Set##TYPENAME(                            \
+      const FieldDescriptor* field, PASSTYPE value) {                        \
+    USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE);                       \
+    if (field->is_extension()) {                                             \
+      return extensions_->Set##TYPENAME(field->number(), value);             \
+    } else {                                                                 \
+      SetField<TYPE>(field, value);                                          \
+    }                                                                        \
+  }                                                                          \
+                                                                             \
+  PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME(                \
+      const FieldDescriptor* field, int index) const {                       \
+    USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE);               \
+    if (field->is_extension()) {                                             \
+      return extensions_->GetRepeated##TYPENAME(field->number(), index);     \
+    } else {                                                                 \
+      return GetRepeatedField<TYPE>(field, index);                           \
+    }                                                                        \
+  }                                                                          \
+                                                                             \
+  void GeneratedMessageReflection::SetRepeated##TYPENAME(                    \
+      const FieldDescriptor* field, int index, PASSTYPE value) {             \
+    USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE);               \
+    if (field->is_extension()) {                                             \
+      extensions_->SetRepeated##TYPENAME(field->number(), index, value);     \
+    } else {                                                                 \
+      SetRepeatedField<TYPE>(field, index, value);                           \
+    }                                                                        \
+  }                                                                          \
+                                                                             \
+  void GeneratedMessageReflection::Add##TYPENAME(                            \
+      const FieldDescriptor* field, PASSTYPE value) {                        \
+    USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE);                       \
+    if (field->is_extension()) {                                             \
+      extensions_->Add##TYPENAME(field->number(), value);                    \
+    } else {                                                                 \
+      AddField<TYPE>(field, value);                                          \
+    }                                                                        \
+  }
+
+DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 )
+DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 )
+DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32)
+DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64)
+DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT )
+DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
+DEFINE_PRIMITIVE_ACCESSORS(Bool  , bool  , bool  , BOOL  )
+#undef DEFINE_PRIMITIVE_ACCESSORS
+
+// -------------------------------------------------------------------
+
+string GeneratedMessageReflection::GetString(
+    const FieldDescriptor* field) const {
+  USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
+  if (field->is_extension()) {
+    return extensions_->GetString(field->number());
+  } else {
+    return *GetField<const string*>(field);
+  }
+}
+
+const string& GeneratedMessageReflection::GetStringReference(
+    const FieldDescriptor* field, string* scratch) const {
+  USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
+  if (field->is_extension()) {
+    return extensions_->GetString(field->number());
+  } else {
+    return *GetField<const string*>(field);
+  }
+}
+
+
+void GeneratedMessageReflection::SetString(
+    const FieldDescriptor* field, const string& value) {
+  USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
+  if (field->is_extension()) {
+    return extensions_->SetString(field->number(), value);
+  } else {
+    string** ptr = MutableField<string*>(field);
+    if (*ptr == DefaultRaw<const string*>(field)) {
+      *ptr = new string(value);
+    } else {
+      (*ptr)->assign(value);
+    }
+  }
+}
+
+
+string GeneratedMessageReflection::GetRepeatedString(
+    const FieldDescriptor* field, int index) const {
+  USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
+  if (field->is_extension()) {
+    return extensions_->GetRepeatedString(field->number(), index);
+  } else {
+    return GetRepeatedField<string>(field, index);
+  }
+}
+
+const string& GeneratedMessageReflection::GetRepeatedStringReference(
+    const FieldDescriptor* field, int index, string* scratch) const {
+  USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
+  if (field->is_extension()) {
+    return extensions_->GetRepeatedString(field->number(), index);
+  } else {
+    return GetRepeatedField<string>(field, index);
+  }
+}
+
+
+void GeneratedMessageReflection::SetRepeatedString(
+    const FieldDescriptor* field, int index, const string& value) {
+  USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
+  if (field->is_extension()) {
+    extensions_->SetRepeatedString(field->number(), index, value);
+  } else {
+    SetRepeatedField<string>(field, index, value);
+  }
+}
+
+
+void GeneratedMessageReflection::AddString(
+    const FieldDescriptor* field, const string& value) {
+  USAGE_CHECK_ALL(AddString, REPEATED, STRING);
+  if (field->is_extension()) {
+    extensions_->AddString(field->number(), value);
+  } else {
+    AddField<string>(field, value);
+  }
+}
+
+
+// -------------------------------------------------------------------
+
+const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
+    const FieldDescriptor* field) const {
+  USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM);
+
+  int value;
+  if (field->is_extension()) {
+    value = extensions_->GetEnum(field->number());
+  } else {
+    value = GetField<int>(field);
+  }
+  const EnumValueDescriptor* result =
+    field->enum_type()->FindValueByNumber(value);
+  GOOGLE_CHECK(result != NULL);
+  return result;
+}
+
+void GeneratedMessageReflection::SetEnum(const FieldDescriptor* field,
+                                         const EnumValueDescriptor* value) {
+  USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM);
+  USAGE_CHECK_ENUM_VALUE(SetEnum);
+
+  if (field->is_extension()) {
+    extensions_->SetEnum(field->number(), value->number());
+  } else {
+    SetField<int>(field, value->number());
+  }
+}
+
+const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
+    const FieldDescriptor* field, int index) const {
+  USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM);
+
+  int value;
+  if (field->is_extension()) {
+    value = extensions_->GetRepeatedEnum(field->number(), index);
+  } else {
+    value = GetRepeatedField<int>(field, index);
+  }
+  const EnumValueDescriptor* result =
+    field->enum_type()->FindValueByNumber(value);
+  GOOGLE_CHECK(result != NULL);
+  return result;
+}
+
+void GeneratedMessageReflection::SetRepeatedEnum(
+    const FieldDescriptor* field, int index,
+    const EnumValueDescriptor* value) {
+  USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
+  USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
+
+  if (field->is_extension()) {
+    extensions_->SetRepeatedEnum(field->number(), index, value->number());
+  } else {
+    SetRepeatedField<int>(field, index, value->number());
+  }
+}
+
+void GeneratedMessageReflection::AddEnum(const FieldDescriptor* field,
+                                         const EnumValueDescriptor* value) {
+  USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
+  USAGE_CHECK_ENUM_VALUE(AddEnum);
+
+  if (field->is_extension()) {
+    extensions_->AddEnum(field->number(), value->number());
+  } else {
+    AddField<int>(field, value->number());
+  }
+}
+
+// -------------------------------------------------------------------
+
+const Message& GeneratedMessageReflection::GetMessage(
+    const FieldDescriptor* field) const {
+  USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
+
+  if (field->is_extension()) {
+    return extensions_->GetMessage(field->number());
+  } else {
+    const Message* result = GetRaw<const Message*>(field);
+    if (result == NULL) {
+      result = DefaultRaw<const Message*>(field);
+    }
+    return *result;
+  }
+}
+
+Message* GeneratedMessageReflection::MutableMessage(
+    const FieldDescriptor* field) {
+  USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
+
+  if (field->is_extension()) {
+    return extensions_->MutableMessage(field->number());
+  } else {
+    Message** result = MutableField<Message*>(field);
+    if (*result == NULL) {
+      const Message* default_message = DefaultRaw<const Message*>(field);
+      *result = default_message->New();
+      (*result)->CopyFrom(*default_message);
+    }
+    return *result;
+  }
+}
+
+const Message& GeneratedMessageReflection::GetRepeatedMessage(
+    const FieldDescriptor* field, int index) const {
+  USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
+
+  if (field->is_extension()) {
+    return extensions_->GetRepeatedMessage(field->number(), index);
+  } else {
+    return GetRepeatedField<Message>(field, index);
+  }
+}
+
+Message* GeneratedMessageReflection::MutableRepeatedMessage(
+    const FieldDescriptor* field, int index) {
+  USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
+
+  if (field->is_extension()) {
+    return extensions_->MutableRepeatedMessage(field->number(), index);
+  } else {
+    return MutableRepeatedField<Message>(field, index);
+  }
+}
+
+Message* GeneratedMessageReflection::AddMessage(const FieldDescriptor* field) {
+  USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
+
+  if (field->is_extension()) {
+    return extensions_->AddMessage(field->number());
+  } else {
+    return AddField<Message>(field);
+  }
+}
+
+// -------------------------------------------------------------------
+
+const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
+    const string& name) const {
+  if (extensions_ == NULL) return NULL;
+  return extensions_->FindKnownExtensionByName(name);
+}
+
+const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
+    int number) const {
+  if (extensions_ == NULL) return NULL;
+  return extensions_->FindKnownExtensionByNumber(number);
+}
+
+// ===================================================================
+// Some private helpers.
+
+// These simple template accessors obtain pointers (or references) to
+// the given field.
+template <typename Type>
+inline const Type& GeneratedMessageReflection::GetRaw(
+    const FieldDescriptor* field) const {
+  const void* ptr = reinterpret_cast<const uint8*>(base_) +
+                    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()];
+  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_) +
+                    offsets_[field->index()];
+  return *reinterpret_cast<const Type*>(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));
+}
+
+inline void GeneratedMessageReflection::SetBit(
+    const FieldDescriptor* field) {
+  has_bits_[field->index() / 32] |= (1 << (field->index() % 32));
+}
+
+inline void GeneratedMessageReflection::ClearBit(
+    const FieldDescriptor* field) {
+  has_bits_[field->index() / 32] &= ~(1 << (field->index() % 32));
+}
+
+// Template implementations of basic accessors.  Inline because each
+// template instance is only called from one location.  These are
+// used for all types except messages.
+template <typename Type>
+inline const Type& GeneratedMessageReflection::GetField(
+    const FieldDescriptor* field) const {
+  return GetRaw<Type>(field);
+}
+
+template <typename Type>
+inline void GeneratedMessageReflection::SetField(
+    const FieldDescriptor* field, const Type& value) {
+  *MutableRaw<Type>(field) = value;
+  SetBit(field);
+}
+
+template <typename Type>
+inline Type* GeneratedMessageReflection::MutableField(
+    const FieldDescriptor* field) {
+  SetBit(field);
+  return MutableRaw<Type>(field);
+}
+
+template <typename Type>
+inline const Type& GeneratedMessageReflection::GetRepeatedField(
+    const FieldDescriptor* field, int index) const {
+  return *reinterpret_cast<const Type*>(
+    GetRaw<GenericRepeatedField>(field).GenericGet(index));
+}
+
+template <typename Type>
+inline void GeneratedMessageReflection::SetRepeatedField(
+    const FieldDescriptor* field, int index, const Type& value) {
+  GenericRepeatedField* repeated = MutableRaw<GenericRepeatedField>(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);
+  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);
+  *reinterpret_cast<Type*>(repeated->GenericAdd()) = value;
+}
+
+template <typename Type>
+inline Type* GeneratedMessageReflection::AddField(
+    const FieldDescriptor* field) {
+  GenericRepeatedField* repeated = MutableRaw<GenericRepeatedField>(field);
+  return reinterpret_cast<Type*>(repeated->GenericAdd());
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
new file mode 100644
index 0000000..579d6ab
--- /dev/null
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -0,0 +1,300 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/message.h>
+#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 {
+namespace internal {
+
+// Defined in this file.
+class GeneratedMessageReflection;
+
+// Defined in other files.
+class ExtensionSet;             // extension_set.h
+
+// THIS CLASS IS NOT INTENDED FOR DIRECT USE.  It is intended for use
+// by generated code.  This class is just a big hack that reduces code
+// size.
+//
+// A GeneratedMessageReflection is an implementation of Message::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.
+//
+// It is required that the user represents fields of each type in a standard
+// way, so that GeneratedMessageReflection can cast the void* pointer to
+// the appropriate type.  For primitive fields and string fields, each field
+// should be represented using the obvious C++ primitive type.  Enums and
+// Messages are different:
+//  - Singular Message fields are stored as a pointer to a Message.  These
+//    should start out NULL, except for in the default instance where they
+//    should start out pointing to other default instances.
+//  - Enum fields are stored as an int.  This int must always contain
+//    a valid value, such that EnumDescriptor::FindValueByNumber() would
+//    not return NULL.
+//  - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
+//    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 {
+ 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
+  //                  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
+  //                  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[i / 32] & (1 << (i % 32))
+  //   extensions:    The ExtensionSet for this message, or NULL if the
+  //                  message type has no extension ranges.
+  GeneratedMessageReflection(const Descriptor* descriptor,
+                             void* base, const void* default_base,
+                             const int offsets[], uint32 has_bits[],
+                             ExtensionSet* extensions);
+  ~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,
+                                   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,
+                                           int index, string* scratch) const;
+  const EnumValueDescriptor* GetRepeatedEnum(const FieldDescriptor* field,
+                                             int index) const;
+  const Message& GetRepeatedMessage(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);
+  // 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);
+
+  const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
+  const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
+
+ private:
+  friend class GeneratedMessage;
+
+  const Descriptor* descriptor_;
+  void* base_;
+  const void* default_base_;
+  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_;
+
+  // 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_;
+
+  template <typename Type>
+  inline const Type& GetRaw(const FieldDescriptor* field) const;
+  template <typename Type>
+  inline Type* MutableRaw(const FieldDescriptor* field);
+  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);
+
+  template <typename Type>
+  inline const Type& GetField(const FieldDescriptor* field) const;
+  template <typename Type>
+  inline void SetField(const FieldDescriptor* field, const Type& value);
+  template <typename Type>
+  inline Type* MutableField(const FieldDescriptor* field);
+  template <typename Type>
+  inline const Type& GetRepeatedField(const FieldDescriptor* field,
+                                      int index) const;
+  template <typename Type>
+  inline void SetRepeatedField(const FieldDescriptor* field, int index,
+                               const Type& value);
+  template <typename Type>
+  inline Type* MutableRepeatedField(const FieldDescriptor* field, int index);
+  template <typename Type>
+  inline void AddField(const FieldDescriptor* field, const Type& value);
+  template <typename Type>
+  inline Type* AddField(const FieldDescriptor* field);
+
+  int GetExtensionNumberOrDie(const Descriptor* type) const;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
+};
+
+// Returns the offset of the given field within the given aggregate type.
+// This is equivalent to the ANSI C offsetof() macro.  However, according
+// to the C++ standard, offsetof() only works on POD types, and GCC
+// enforces this requirement with a warning.  In practice, this rule is
+// unnecessarily strict; there is probably no compiler or platform on
+// which the offsets of the direct fields of a class are non-constant.
+// Fields inherited from superclasses *can* have non-constant offsets,
+// but that's not what this macro will be used for.
+//
+// Note that we calculate relative to the pointer value 16 here since if we
+// just use zero, GCC complains about dereferencing a NULL pointer.  We
+// choose 16 rather than some other number just in case the compiler would
+// be confused by an unaligned pointer.
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
+  (reinterpret_cast<const char*>(                             \
+     &reinterpret_cast<const TYPE*>(16)->FIELD) -             \
+   reinterpret_cast<const char*>(16))
+
+// There are some places in proto2 where dynamic_cast would be useful as an
+// optimization.  For example, take Message::MergeFrom(const Message& other).
+// For a given generated message FooMessage, we generate these two methods:
+//   void MergeFrom(const FooMessage& other);
+//   void MergeFrom(const Message& other);
+// The former method can be implemented directly in terms of FooMessage's
+// inline accessors, but the latter method must work with the reflection
+// interface.  However, if the parameter to the latter method is actually of
+// type FooMessage, then we'd like to be able to just call the other method
+// as an optimization.  So, we use dynamic_cast to check this.
+//
+// That said, dynamic_cast requires RTTI, which many people like to disable
+// for performance and code size reasons.  When RTTI is not available, we
+// still need to produce correct results.  So, in this case we have to fall
+// back to using reflection, which is what we would have done anyway if the
+// objects were not of the exact same class.
+//
+// dynamic_cast_if_available() implements this logic.  If RTTI is
+// enabled, it does a dynamic_cast.  If RTTI is disabled, it just returns
+// NULL.
+//
+// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI.
+// On MSVC, this should be detected automatically.
+template<typename To, typename From>
+inline To dynamic_cast_if_available(From from) {
+#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
+  return NULL;
+#else
+  return dynamic_cast<To>(from);
+#endif
+}
+
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc
new file mode 100644
index 0000000..bde7fac
--- /dev/null
+++ b/src/google/protobuf/generated_message_reflection_unittest.cc
@@ -0,0 +1,251 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// To test GeneratedMessageReflection, we actually let the protocol compiler
+// generate a full protocol message implementation and then test its
+// reflection interface.  This is much easier and more maintainable than
+// trying to create our own Message class for GeneratedMessageReflection
+// to wrap.
+//
+// The tests here closely mirror some of the tests in
+// compiler/cpp/unittest, except using the reflection interface
+// rather than generated accessors.
+
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/unittest.pb.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
+const FieldDescriptor* F(const string& name) {
+  const FieldDescriptor* result =
+    unittest::TestAllTypes::descriptor()->FindFieldByName(name);
+  GOOGLE_CHECK(result != NULL);
+  return result;
+}
+
+TEST(GeneratedMessageReflectionTest, Defaults) {
+  // Check that all default values are set correctly in the initial message.
+  unittest::TestAllTypes message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllTypes::descriptor());
+
+  reflection_tester.ExpectClearViaReflection(*message.GetReflection());
+
+  const Message::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")));
+  EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &reflection.GetMessage(F("optional_nested_message")));
+  EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
+            &reflection.GetMessage(F("optional_foreign_message")));
+  EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
+            &reflection.GetMessage(F("optional_import_message")));
+}
+
+TEST(GeneratedMessageReflectionTest, Accessors) {
+  // Set every field to a unique value then go back and check all those
+  // values.
+  unittest::TestAllTypes message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllTypes::descriptor());
+
+  reflection_tester.SetAllFieldsViaReflection(message.GetReflection());
+  TestUtil::ExpectAllFieldsSet(message);
+  reflection_tester.ExpectAllFieldsSetViaReflection(*message.GetReflection());
+
+  reflection_tester.ModifyRepeatedFieldsViaReflection(message.GetReflection());
+  TestUtil::ExpectRepeatedFieldsModified(message);
+}
+
+TEST(GeneratedMessageReflectionTest, GetStringReference) {
+  // Test that GetStringReference() returns the underlying string when it is
+  // a normal string field.
+  unittest::TestAllTypes message;
+  message.set_optional_string("foo");
+  message.add_repeated_string("foo");
+
+  const Message::Reflection& reflection = *message.GetReflection();
+  string scratch;
+
+  EXPECT_EQ(&message.optional_string(),
+      &reflection.GetStringReference(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))
+    << "For simple string fields, GetRepeatedStringReference() should return "
+       "a reference to the underlying string.";
+}
+
+
+TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) {
+  // Check that after setting all fields and then clearing, getting an
+  // embedded message does NOT return the default instance.
+  unittest::TestAllTypes message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllTypes::descriptor());
+
+  TestUtil::SetAllFields(&message);
+  message.Clear();
+
+  const Message::Reflection& reflection = *message.GetReflection();
+
+  EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+            &reflection.GetMessage(F("optionalgroup")));
+  EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &reflection.GetMessage(F("optional_nested_message")));
+  EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+            &reflection.GetMessage(F("optional_foreign_message")));
+  EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+            &reflection.GetMessage(F("optional_import_message")));
+}
+
+TEST(GeneratedMessageReflectionTest, Extensions) {
+  // Set every extension to a unique value then go back and check all those
+  // values.
+  unittest::TestAllExtensions message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllExtensions::descriptor());
+
+  reflection_tester.SetAllFieldsViaReflection(message.GetReflection());
+  TestUtil::ExpectAllExtensionsSet(message);
+  reflection_tester.ExpectAllFieldsSetViaReflection(*message.GetReflection());
+
+  reflection_tester.ModifyRepeatedFieldsViaReflection(message.GetReflection());
+  TestUtil::ExpectRepeatedExtensionsModified(message);
+}
+
+TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) {
+  const Message::Reflection& reflection =
+    *unittest::TestAllExtensions::default_instance().GetReflection();
+
+  const FieldDescriptor* extension1 =
+    unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+      "optional_int32_extension");
+  const FieldDescriptor* extension2 =
+    unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+      "repeated_string_extension");
+
+  EXPECT_EQ(extension1,
+            reflection.FindKnownExtensionByNumber(extension1->number()));
+  EXPECT_EQ(extension2,
+            reflection.FindKnownExtensionByNumber(extension2->number()));
+
+  // Non-existent extension.
+  EXPECT_TRUE(reflection.FindKnownExtensionByNumber(62341) == NULL);
+
+  // Extensions of TestAllExtensions should not show up as extensions of
+  // other types.
+  EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()->
+              FindKnownExtensionByNumber(extension1->number()) == NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) {
+  const Message::Reflection& reflection =
+    *unittest::TestAllExtensions::default_instance().GetReflection();
+
+  const FieldDescriptor* extension1 =
+    unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+      "optional_int32_extension");
+  const FieldDescriptor* extension2 =
+    unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+      "repeated_string_extension");
+
+  EXPECT_EQ(extension1,
+            reflection.FindKnownExtensionByName(extension1->full_name()));
+  EXPECT_EQ(extension2,
+            reflection.FindKnownExtensionByName(extension2->full_name()));
+
+  // Non-existent extension.
+  EXPECT_TRUE(reflection.FindKnownExtensionByName("no_such_ext") == NULL);
+
+  // Extensions of TestAllExtensions should not show up as extensions of
+  // other types.
+  EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()->
+              FindKnownExtensionByName(extension1->full_name()) == NULL);
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST(GeneratedMessageReflectionTest, UsageErrors) {
+  unittest::TestAllTypes message;
+  Message::Reflection* reflection = message.GetReflection();
+  const Descriptor* descriptor = message.GetDescriptor();
+
+#define f(NAME) descriptor->FindFieldByName(NAME)
+
+  // Testing every single failure mode would be too much work.  Let's just
+  // check a few.
+  EXPECT_DEATH(
+    reflection->GetInt32(descriptor->FindFieldByName("optional_int64")),
+    "Protocol Buffer reflection usage error:\n"
+    "  Method      : google::protobuf::Message::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")),
+    "Protocol Buffer reflection usage error:\n"
+    "  Method      : google::protobuf::Message::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")),
+    "Protocol Buffer reflection usage error:\n"
+    "  Method      : google::protobuf::Message::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")),
+    "Protocol Buffer reflection usage error:\n"
+    "  Method      : google::protobuf::Message::Reflection::HasField\n"
+    "  Message type: protobuf_unittest.TestAllTypes\n"
+    "  Field       : protobuf_unittest.ForeignMessage.c\n"
+    "  Problem     : Field does not match message type.");
+
+#undef f
+}
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+
+}  // namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
new file mode 100644
index 0000000..58c44dc
--- /dev/null
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -0,0 +1,757 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This implementation is heavily optimized to make reads and writes
+// of small values (especially varints) as fast as possible.  In
+// particular, we optimize for the common case that a read or a write
+// will not cross the end of the buffer, since we can avoid a lot
+// of branching in this case.
+
+#include <stack>
+#include <limits.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+namespace {
+
+static const int kDefaultTotalBytesLimit = 64 << 20;  // 64MB
+
+static const int kDefaultTotalBytesWarningThreshold = 32 << 20;  // 32MB
+static const int kDefaultRecursionLimit = 64;
+
+static const int kMaxVarintBytes = 10;
+static const int kMaxVarint32Bytes = 5;
+
+
+}  // namespace
+
+// CodedInputStream ==================================================
+
+CodedInputStream::CodedInputStream(ZeroCopyInputStream* input)
+  : input_(input),
+    buffer_(NULL),
+    buffer_size_(0),
+    total_bytes_read_(0),
+    overflow_bytes_(0),
+
+    last_tag_(0),
+    legitimate_message_end_(false),
+
+    aliasing_enabled_(false),
+
+    current_limit_(INT_MAX),
+    buffer_size_after_limit_(0),
+
+    total_bytes_limit_(kDefaultTotalBytesLimit),
+    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
+
+    recursion_depth_(0),
+    recursion_limit_(kDefaultRecursionLimit) {
+}
+
+CodedInputStream::~CodedInputStream() {
+  int backup_bytes = buffer_size_ + buffer_size_after_limit_ + overflow_bytes_;
+  if (backup_bytes > 0) {
+    // We still have bytes left over from the last buffer.  Back up over
+    // them.
+    input_->BackUp(backup_bytes);
+  }
+}
+
+
+inline void CodedInputStream::RecomputeBufferLimits() {
+  buffer_size_ += buffer_size_after_limit_;
+  int closest_limit = min(current_limit_, total_bytes_limit_);
+  if (closest_limit < total_bytes_read_) {
+    // The limit position is in the current buffer.  We must adjust
+    // the buffer size accordingly.
+    buffer_size_after_limit_ = total_bytes_read_ - closest_limit;
+    buffer_size_ -= buffer_size_after_limit_;
+  } else {
+    buffer_size_after_limit_ = 0;
+  }
+}
+
+CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
+  // Current position relative to the beginning of the stream.
+  int current_position = total_bytes_read_ -
+      (buffer_size_ + buffer_size_after_limit_);
+
+  Limit old_limit = current_limit_;
+
+  // security: byte_limit is possibly evil, so check for negative values
+  // and overflow.
+  if (byte_limit >= 0 &&
+      byte_limit <= INT_MAX - current_position) {
+    current_limit_ = current_position + byte_limit;
+  } else {
+    // Negative or overflow.
+    current_limit_ = INT_MAX;
+  }
+
+  // We need to enforce all limits, not just the new one, so if the previous
+  // limit was before the new requested limit, we continue to enforce the
+  // previous limit.
+  current_limit_ = min(current_limit_, old_limit);
+
+  RecomputeBufferLimits();
+  return old_limit;
+}
+
+void CodedInputStream::PopLimit(Limit limit) {
+  // The limit passed in is actually the *old* limit, which we returned from
+  // PushLimit().
+  current_limit_ = limit;
+  RecomputeBufferLimits();
+
+  // We may no longer be at a legitimate message end.  ReadTag() needs to be
+  // called again to find out.
+  legitimate_message_end_ = false;
+}
+
+int CodedInputStream::BytesUntilLimit() {
+  if (current_limit_ == INT_MAX) return -1;
+  int current_position = total_bytes_read_ -
+      (buffer_size_ + buffer_size_after_limit_);
+
+  return current_limit_ - current_position;
+}
+
+void CodedInputStream::SetTotalBytesLimit(
+    int total_bytes_limit, int warning_threshold) {
+  // Make sure the limit isn't already past, since this could confuse other
+  // code.
+  int current_position = total_bytes_read_ -
+      (buffer_size_ + buffer_size_after_limit_);
+  total_bytes_limit_ = max(current_position, total_bytes_limit);
+  total_bytes_warning_threshold_ = warning_threshold;
+  RecomputeBufferLimits();
+}
+
+void CodedInputStream::PrintTotalBytesLimitError() {
+  GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too "
+                "big (more than " << total_bytes_limit_
+             << " bytes).  To increase the limit (or to disable these "
+                "warnings), see CodedInputStream::SetTotalBytesLimit() "
+                "in google/protobuf/io/coded_stream.h.";
+}
+
+bool CodedInputStream::Skip(int count) {
+  if (count < 0) return false;  // security: count is often user-supplied
+
+  if (count <= buffer_size_) {
+    // Just skipping within the current buffer.  Easy.
+    Advance(count);
+    return true;
+  }
+
+  if (buffer_size_after_limit_ > 0) {
+    // We hit a limit inside this buffer.  Advance to the limit and fail.
+    Advance(buffer_size_);
+    return false;
+  }
+
+  count -= buffer_size_;
+  buffer_ = NULL;
+  buffer_size_ = 0;
+
+  // Make sure this skip doesn't try to skip past the current limit.
+  int closest_limit = min(current_limit_, total_bytes_limit_);
+  int bytes_until_limit = closest_limit - total_bytes_read_;
+  if (bytes_until_limit < count) {
+    // We hit the limit.  Skip up to it then fail.
+    total_bytes_read_ = closest_limit;
+    input_->Skip(bytes_until_limit);
+    return false;
+  }
+
+  total_bytes_read_ += count;
+  return input_->Skip(count);
+}
+
+bool CodedInputStream::ReadRaw(void* buffer, int size) {
+  while (buffer_size_ < size) {
+    // Reading past end of buffer.  Copy what we have, then refresh.
+    memcpy(buffer, buffer_, buffer_size_);
+    buffer = reinterpret_cast<uint8*>(buffer) + buffer_size_;
+    size -= buffer_size_;
+    if (!Refresh()) return false;
+  }
+
+  memcpy(buffer, buffer_, size);
+  Advance(size);
+
+  return true;
+}
+
+bool CodedInputStream::ReadString(string* buffer, int size) {
+  if (size < 0) return false;  // security: size is often user-supplied
+
+  if (!buffer->empty()) {
+    buffer->clear();
+  }
+
+  if (size < buffer_size_) {
+    STLStringResizeUninitialized(buffer, size);
+    memcpy((uint8*)buffer->data(), buffer_, size);
+    Advance(size);
+    return true;
+  }
+
+  while (buffer_size_ < size) {
+    // Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
+    if (buffer_size_ != 0) {
+      // Note:  string1.append(string2) is O(string2.size()) (as opposed to
+      //   O(string1.size() + string2.size()), which would be bad).
+      buffer->append(reinterpret_cast<const char*>(buffer_), buffer_size_);
+    }
+    size -= buffer_size_;
+    if (!Refresh()) return false;
+  }
+
+  buffer->append(reinterpret_cast<const char*>(buffer_), size);
+  Advance(size);
+
+  return true;
+}
+
+
+bool CodedInputStream::ReadLittleEndian32(uint32* value) {
+  uint8 bytes[sizeof(*value)];
+
+  const uint8* ptr;
+  if (buffer_size_ >= sizeof(*value)) {
+    // Fast path:  Enough bytes in the buffer to read directly.
+    ptr = buffer_;
+    Advance(sizeof(*value));
+  } else {
+    // Slow path:  Had to read past the end of the buffer.
+    if (!ReadRaw(bytes, sizeof(*value))) return false;
+    ptr = bytes;
+  }
+
+  *value = (static_cast<uint32>(ptr[0])      ) |
+           (static_cast<uint32>(ptr[1]) <<  8) |
+           (static_cast<uint32>(ptr[2]) << 16) |
+           (static_cast<uint32>(ptr[3]) << 24);
+  return true;
+}
+
+bool CodedInputStream::ReadLittleEndian64(uint64* value) {
+  uint8 bytes[sizeof(*value)];
+
+  const uint8* ptr;
+  if (buffer_size_ >= sizeof(*value)) {
+    // Fast path:  Enough bytes in the buffer to read directly.
+    ptr = buffer_;
+    Advance(sizeof(*value));
+  } else {
+    // Slow path:  Had to read past the end of the buffer.
+    if (!ReadRaw(bytes, sizeof(*value))) return false;
+    ptr = bytes;
+  }
+
+  uint32 part0 = (static_cast<uint32>(ptr[0])      ) |
+                 (static_cast<uint32>(ptr[1]) <<  8) |
+                 (static_cast<uint32>(ptr[2]) << 16) |
+                 (static_cast<uint32>(ptr[3]) << 24);
+  uint32 part1 = (static_cast<uint32>(ptr[4])      ) |
+                 (static_cast<uint32>(ptr[5]) <<  8) |
+                 (static_cast<uint32>(ptr[6]) << 16) |
+                 (static_cast<uint32>(ptr[7]) << 24);
+  *value = static_cast<uint64>(part0) |
+          (static_cast<uint64>(part1) << 32);
+  return true;
+}
+
+bool CodedInputStream::ReadVarint32Fallback(uint32* value) {
+  if (buffer_size_ >= kMaxVarintBytes ||
+      // Optimization:  If the varint ends at exactly the end of the buffer,
+      // we can detect that and still use the fast path.
+      (buffer_size_ != 0 && !(buffer_[buffer_size_-1] & 0x80))) {
+    // Fast path:  We have enough bytes left in the buffer to guarantee that
+    // this read won't cross the end, so we can skip the checks.
+    const uint8* ptr = buffer_;
+    uint32 b;
+    uint32 result;
+
+    b = *(ptr++); result  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
+    b = *(ptr++); result |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
+    b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
+    b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
+    b = *(ptr++); result |=  b         << 28; if (!(b & 0x80)) goto done;
+
+    // If the input is larger than 32 bits, we still need to read it all
+    // and discard the high-order bits.
+    for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
+      b = *(ptr++); if (!(b & 0x80)) goto done;
+    }
+
+    // We have overrun the maximum size of a varint (10 bytes).  Assume
+    // the data is corrupt.
+    return false;
+
+   done:
+    Advance(ptr - buffer_);
+    *value = result;
+    return true;
+
+  } else {
+    // Optimization:  If we're at a limit, detect that quickly.  (This is
+    // common when reading tags.)
+    while (buffer_size_ == 0) {
+      // Detect cases where we definitely hit a byte limit without calling
+      // Refresh().
+      if (// If we hit a limit, buffer_size_after_limit_ will be non-zero.
+          buffer_size_after_limit_ > 0 &&
+          // Make sure that the limit we hit is not total_bytes_limit_, since
+          // in that case we still need to call Refresh() so that it prints an
+          // error.
+          total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) {
+        // We hit a byte limit.
+        legitimate_message_end_ = true;
+        return false;
+      }
+
+      // Call refresh.
+      if (!Refresh()) {
+        // Refresh failed.  Make sure that it failed due to EOF, not because
+        // we hit total_bytes_limit_, which, unlike normal limits, is not a
+        // valid place to end a message.
+        int current_position = total_bytes_read_ - buffer_size_after_limit_;
+        if (current_position >= total_bytes_limit_) {
+          // Hit total_bytes_limit_.  But if we also hit the normal limit,
+          // we're still OK.
+          legitimate_message_end_ = current_limit_ == total_bytes_limit_;
+        } else {
+          legitimate_message_end_ = true;
+        }
+        return false;
+      }
+    }
+
+    // Slow path:  Just do a 64-bit read.
+    uint64 result;
+    if (!ReadVarint64(&result)) return false;
+    *value = (uint32)result;
+    return true;
+  }
+}
+
+bool CodedInputStream::ReadVarint64(uint64* value) {
+  if (buffer_size_ >= kMaxVarintBytes ||
+      // Optimization:  If the varint ends at exactly the end of the buffer,
+      // we can detect that and still use the fast path.
+      (buffer_size_ != 0 && !(buffer_[buffer_size_-1] & 0x80))) {
+    // Fast path:  We have enough bytes left in the buffer to guarantee that
+    // this read won't cross the end, so we can skip the checks.
+
+    const uint8* ptr = buffer_;
+    uint32 b;
+
+    // Splitting into 32-bit pieces gives better performance on 32-bit
+    // processors.
+    uint32 part0 = 0, part1 = 0, part2 = 0;
+
+    b = *(ptr++); part0  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
+    b = *(ptr++); part0 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
+    b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
+    b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
+    b = *(ptr++); part1  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
+    b = *(ptr++); part1 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
+    b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
+    b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
+    b = *(ptr++); part2  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
+    b = *(ptr++); part2 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
+
+    // We have overrun the maximum size of a varint (10 bytes).  The data
+    // must be corrupt.
+    return false;
+
+   done:
+    Advance(ptr - buffer_);
+    *value = (static_cast<uint64>(part0)      ) |
+             (static_cast<uint64>(part1) << 28) |
+             (static_cast<uint64>(part2) << 56);
+    return true;
+
+  } else {
+    // Slow path:  This read might cross the end of the buffer, so we
+    // need to check and refresh the buffer if and when it does.
+
+    uint64 result = 0;
+    int count = 0;
+    uint32 b;
+
+    do {
+      if (count == kMaxVarintBytes) return false;
+      while (buffer_size_ == 0) {
+        if (!Refresh()) return false;
+      }
+      b = *buffer_;
+      result |= static_cast<uint64>(b & 0x7F) << (7 * count);
+      Advance(1);
+      ++count;
+    } while(b & 0x80);
+
+    *value = result;
+    return true;
+  }
+}
+
+bool CodedInputStream::Refresh() {
+  if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0) {
+    // We've hit a limit.  Stop.
+    buffer_ += buffer_size_;
+    buffer_size_ = 0;
+
+    int current_position = total_bytes_read_ - buffer_size_after_limit_;
+
+    if (current_position >= total_bytes_limit_ &&
+        total_bytes_limit_ != current_limit_) {
+      // Hit total_bytes_limit_.
+      PrintTotalBytesLimitError();
+    }
+
+    return false;
+  }
+
+  if (total_bytes_warning_threshold_ >= 0 &&
+      total_bytes_read_ >= total_bytes_warning_threshold_) {
+      GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message.  If the "
+                      "message turns out to be larger than "
+                   << total_bytes_limit_ << " bytes, parsing will be halted "
+                      "for security reasons.  To increase the limit (or to "
+                      "disable these warnings), see "
+                      "CodedInputStream::SetTotalBytesLimit() in "
+                      "google/protobuf/io/coded_stream.h.";
+
+    // Don't warn again for this stream.
+    total_bytes_warning_threshold_ = -1;
+  }
+
+  const void* void_buffer;
+  if (input_->Next(&void_buffer, &buffer_size_)) {
+    buffer_ = reinterpret_cast<const uint8*>(void_buffer);
+    GOOGLE_CHECK_GE(buffer_size_, 0);
+
+    if (total_bytes_read_ <= INT_MAX - buffer_size_) {
+      total_bytes_read_ += buffer_size_;
+    } else {
+      // Overflow.  Reset buffer_size_ to not include the bytes beyond INT_MAX.
+      // We can't get that far anyway, because total_bytes_limit_ is guaranteed
+      // to be less than it.  We need to keep track of the number of bytes
+      // we discarded, though, so that we can call input_->BackUp() to back
+      // up over them on destruction.
+
+      // The following line is equivalent to:
+      //   overflow_bytes_ = total_bytes_read_ + buffer_size_ - INT_MAX;
+      // except that it avoids overflows.  Signed integer overflow has
+      // undefined results according to the C standard.
+      overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size_);
+      buffer_size_ -= overflow_bytes_;
+      total_bytes_read_ = INT_MAX;
+    }
+
+    RecomputeBufferLimits();
+    return true;
+  } else {
+    buffer_ = NULL;
+    buffer_size_ = 0;
+    return false;
+  }
+}
+
+// CodedOutputStream =================================================
+
+CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
+  : output_(output),
+    buffer_(NULL),
+    buffer_size_(0),
+    total_bytes_(0) {
+}
+
+CodedOutputStream::~CodedOutputStream() {
+  if (buffer_size_ > 0) {
+    output_->BackUp(buffer_size_);
+  }
+}
+
+bool CodedOutputStream::WriteRaw(const void* data, int size) {
+  while (buffer_size_ < size) {
+    memcpy(buffer_, data, buffer_size_);
+    size -= buffer_size_;
+    data = reinterpret_cast<const uint8*>(data) + buffer_size_;
+    if (!Refresh()) return false;
+  }
+
+  memcpy(buffer_, data, size);
+  Advance(size);
+  return true;
+}
+
+
+bool CodedOutputStream::WriteLittleEndian32(uint32 value) {
+  uint8 bytes[sizeof(value)];
+
+  bool use_fast = buffer_size_ >= sizeof(value);
+  uint8* ptr = use_fast ? buffer_ : bytes;
+
+  ptr[0] = static_cast<uint8>(value      );
+  ptr[1] = static_cast<uint8>(value >>  8);
+  ptr[2] = static_cast<uint8>(value >> 16);
+  ptr[3] = static_cast<uint8>(value >> 24);
+
+  if (use_fast) {
+    Advance(sizeof(value));
+    return true;
+  } else {
+    return WriteRaw(bytes, sizeof(value));
+  }
+}
+
+bool CodedOutputStream::WriteLittleEndian64(uint64 value) {
+  uint8 bytes[sizeof(value)];
+
+  uint32 part0 = static_cast<uint32>(value);
+  uint32 part1 = static_cast<uint32>(value >> 32);
+
+  bool use_fast = buffer_size_ >= sizeof(value);
+  uint8* ptr = use_fast ? buffer_ : bytes;
+
+  ptr[0] = static_cast<uint8>(part0      );
+  ptr[1] = static_cast<uint8>(part0 >>  8);
+  ptr[2] = static_cast<uint8>(part0 >> 16);
+  ptr[3] = static_cast<uint8>(part0 >> 24);
+  ptr[4] = static_cast<uint8>(part1      );
+  ptr[5] = static_cast<uint8>(part1 >>  8);
+  ptr[6] = static_cast<uint8>(part1 >> 16);
+  ptr[7] = static_cast<uint8>(part1 >> 24);
+
+  if (use_fast) {
+    Advance(sizeof(value));
+    return true;
+  } else {
+    return WriteRaw(bytes, sizeof(value));
+  }
+}
+
+bool CodedOutputStream::WriteVarint32Fallback(uint32 value) {
+  if (buffer_size_ >= kMaxVarint32Bytes) {
+    // Fast path:  We have enough bytes left in the buffer to guarantee that
+    // this write won't cross the end, so we can skip the checks.
+    uint8* target = buffer_;
+
+    target[0] = static_cast<uint8>(value | 0x80);
+    if (value >= (1 << 7)) {
+      target[1] = static_cast<uint8>((value >>  7) | 0x80);
+      if (value >= (1 << 14)) {
+        target[2] = static_cast<uint8>((value >> 14) | 0x80);
+        if (value >= (1 << 21)) {
+          target[3] = static_cast<uint8>((value >> 21) | 0x80);
+          if (value >= (1 << 28)) {
+            target[4] = static_cast<uint8>(value >> 28);
+            Advance(5);
+          } else {
+            target[3] &= 0x7F;
+            Advance(4);
+          }
+        } else {
+          target[2] &= 0x7F;
+          Advance(3);
+        }
+      } else {
+        target[1] &= 0x7F;
+        Advance(2);
+      }
+    } else {
+      target[0] &= 0x7F;
+      Advance(1);
+    }
+
+    return true;
+  } else {
+    // Slow path:  This write might cross the end of the buffer, so we
+    // compose the bytes first then use WriteRaw().
+    uint8 bytes[kMaxVarint32Bytes];
+    int size = 0;
+    while (value > 0x7F) {
+      bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
+      value >>= 7;
+    }
+    bytes[size++] = static_cast<uint8>(value) & 0x7F;
+    return WriteRaw(bytes, size);
+  }
+}
+
+bool CodedOutputStream::WriteVarint64(uint64 value) {
+  if (buffer_size_ >= kMaxVarintBytes) {
+    // Fast path:  We have enough bytes left in the buffer to guarantee that
+    // this write won't cross the end, so we can skip the checks.
+    uint8* target = buffer_;
+
+    // Splitting into 32-bit pieces gives better performance on 32-bit
+    // processors.
+    uint32 part0 = static_cast<uint32>(value      );
+    uint32 part1 = static_cast<uint32>(value >> 28);
+    uint32 part2 = static_cast<uint32>(value >> 56);
+
+    int size;
+
+    // Here we can't really optimize for small numbers, since the value is
+    // split into three parts.  Cheking for numbers < 128, for instance,
+    // would require three comparisons, since you'd have to make sure part1
+    // and part2 are zero.  However, if the caller is using 64-bit integers,
+    // it is likely that they expect the numbers to often be very large, so
+    // we probably don't want to optimize for small numbers anyway.  Thus,
+    // we end up with a hardcoded binary search tree...
+    if (part2 == 0) {
+      if (part1 == 0) {
+        if (part0 < (1 << 14)) {
+          if (part0 < (1 << 7)) {
+            size = 1; goto size1;
+          } else {
+            size = 2; goto size2;
+          }
+        } else {
+          if (part0 < (1 << 21)) {
+            size = 3; goto size3;
+          } else {
+            size = 4; goto size4;
+          }
+        }
+      } else {
+        if (part1 < (1 << 14)) {
+          if (part1 < (1 << 7)) {
+            size = 5; goto size5;
+          } else {
+            size = 6; goto size6;
+          }
+        } else {
+          if (part1 < (1 << 21)) {
+            size = 7; goto size7;
+          } else {
+            size = 8; goto size8;
+          }
+        }
+      }
+    } else {
+      if (part2 < (1 << 7)) {
+        size = 9; goto size9;
+      } else {
+        size = 10; goto size10;
+      }
+    }
+
+    GOOGLE_LOG(FATAL) << "Can't get here.";
+
+    size10: target[9] = static_cast<uint8>((part2 >>  7) | 0x80);
+    size9 : target[8] = static_cast<uint8>((part2      ) | 0x80);
+    size8 : target[7] = static_cast<uint8>((part1 >> 21) | 0x80);
+    size7 : target[6] = static_cast<uint8>((part1 >> 14) | 0x80);
+    size6 : target[5] = static_cast<uint8>((part1 >>  7) | 0x80);
+    size5 : target[4] = static_cast<uint8>((part1      ) | 0x80);
+    size4 : target[3] = static_cast<uint8>((part0 >> 21) | 0x80);
+    size3 : target[2] = static_cast<uint8>((part0 >> 14) | 0x80);
+    size2 : target[1] = static_cast<uint8>((part0 >>  7) | 0x80);
+    size1 : target[0] = static_cast<uint8>((part0      ) | 0x80);
+
+    target[size-1] &= 0x7F;
+    Advance(size);
+    return true;
+  } else {
+    // Slow path:  This write might cross the end of the buffer, so we
+    // compose the bytes first then use WriteRaw().
+    uint8 bytes[kMaxVarintBytes];
+    int size = 0;
+    while (value > 0x7F) {
+      bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
+      value >>= 7;
+    }
+    bytes[size++] = static_cast<uint8>(value) & 0x7F;
+    return WriteRaw(bytes, size);
+  }
+}
+
+bool CodedOutputStream::Refresh() {
+  void* void_buffer;
+  if (output_->Next(&void_buffer, &buffer_size_)) {
+    buffer_ = reinterpret_cast<uint8*>(void_buffer);
+    total_bytes_ += buffer_size_;
+    return true;
+  } else {
+    buffer_ = NULL;
+    buffer_size_ = 0;
+    return false;
+  }
+}
+
+int CodedOutputStream::VarintSize32Fallback(uint32 value) {
+  if (value < (1 << 7)) {
+    return 1;
+  } else if (value < (1 << 14)) {
+    return 2;
+  } else if (value < (1 << 21)) {
+    return 3;
+  } else if (value < (1 << 28)) {
+    return 4;
+  } else {
+    return 5;
+  }
+}
+
+int CodedOutputStream::VarintSize64(uint64 value) {
+  if (value < (1ull << 35)) {
+    if (value < (1ull << 7)) {
+      return 1;
+    } else if (value < (1ull << 14)) {
+      return 2;
+    } else if (value < (1ull << 21)) {
+      return 3;
+    } else if (value < (1ull << 28)) {
+      return 4;
+    } else {
+      return 5;
+    }
+  } else {
+    if (value < (1ull << 42)) {
+      return 6;
+    } else if (value < (1ull << 49)) {
+      return 7;
+    } else if (value < (1ull << 56)) {
+      return 8;
+    } else if (value < (1ull << 63)) {
+      return 9;
+    } else {
+      return 10;
+    }
+  }
+}
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
new file mode 100644
index 0000000..91e5c56
--- /dev/null
+++ b/src/google/protobuf/io/coded_stream.h
@@ -0,0 +1,592 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains the CodedInputStream and CodedOutputStream classes,
+// which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively,
+// and allow you to read or write individual pieces of data in various
+// formats.  In particular, these implement the varint encoding for
+// integers, a simple variable-length encoding in which smaller numbers
+// take fewer bytes.
+//
+// Typically these classes will only be used internally by the protocol
+// buffer library in order to encode and decode protocol buffers.  Clients
+// of the library only need to know about this class if they wish to write
+// custom message parsing or serialization procedures.
+//
+// CodedOutputStream example:
+//   // Write some data to "myfile".  First we write a 4-byte "magic number"
+//   // to identify the file type, then write a length-delimited string.  The
+//   // string is composed of a varint giving the length followed by the raw
+//   // bytes.
+//   int fd = open("myfile", O_WRONLY);
+//   ZeroCopyOutputStream* raw_output = new FileOutputStream(fd);
+//   CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
+//
+//   int magic_number = 1234;
+//   char text[] = "Hello world!";
+//   coded_output->WriteLittleEndian32(magic_number);
+//   coded_output->WriteVarint32(strlen(text));
+//   coded_output->WriteRaw(text, strlen(text));
+//
+//   delete coded_output;
+//   delete raw_output;
+//   close(fd);
+//
+// CodedInputStream example:
+//   // Read a file created by the above code.
+//   int fd = open("myfile", O_RDONLY);
+//   ZeroCopyInputStream* raw_input = new FileInputStream(fd);
+//   CodedInputStream coded_input = new CodedInputStream(raw_input);
+//
+//   coded_input->ReadLittleEndian32(&magic_number);
+//   if (magic_number != 1234) {
+//     cerr << "File not in expected format." << endl;
+//     return;
+//   }
+//
+//   uint32 size;
+//   coded_input->ReadVarint32(&size);
+//
+//   char* text = new char[size + 1];
+//   coded_input->ReadRaw(buffer, size);
+//   text[size] = '\0';
+//
+//   delete coded_input;
+//   delete raw_input;
+//   close(fd);
+//
+//   cout << "Text is: " << text << endl;
+//   delete [] text;
+//
+// For those who are interested, varint encoding is defined as follows:
+//
+// The encoding operates on unsigned integers of up to 64 bits in length.
+// Each byte of the encoded value has the format:
+// * bits 0-6: Seven bits of the number being encoded.
+// * bit 7: Zero if this is the last byte in the encoding (in which
+//   case all remaining bits of the number are zero) or 1 if
+//   more bytes follow.
+// The first byte contains the least-significant 7 bits of the number, the
+// second byte (if present) contains the next-least-significant 7 bits,
+// and so on.  So, the binary number 1011000101011 would be encoded in two
+// bytes as "10101011 00101100".
+//
+// In theory, varint could be used to encode integers of any length.
+// However, for practicality we set a limit at 64 bits.  The maximum encoded
+// length of a number is thus 10 bytes.
+
+#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
+#define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+
+namespace protobuf {
+namespace io {
+
+// Defined in this file.
+class CodedInputStream;
+class CodedOutputStream;
+
+// Defined in other files.
+class ZeroCopyInputStream;           // zero_copy_stream.h
+class ZeroCopyOutputStream;          // zero_copy_stream.h
+
+// Class which reads and decodes binary data which is composed of varint-
+// encoded integers and fixed-width pieces.  Wraps a ZeroCopyInputStream.
+// Most users will not need to deal with CodedInputStream.
+//
+// Most methods of CodedInputStream that return a bool return false if an
+// underlying I/O error occurs or if the data is malformed.  Once such a
+// failure occurs, the CodedInputStream is broken and is no longer useful.
+class LIBPROTOBUF_EXPORT CodedInputStream {
+ public:
+  // Create a CodedInputStream that reads from the given ZeroCopyInputStream.
+  explicit CodedInputStream(ZeroCopyInputStream* input);
+
+  // Destroy the CodedInputStream and position the underlying
+  // ZeroCopyInputStream at the first unread byte.  If an error occurred while
+  // reading (causing a method to return false), then the exact position of
+  // the input stream may be anywhere between the last value that was read
+  // successfully and the stream's byte limit.
+  ~CodedInputStream();
+
+
+  // Skips a number of bytes.  Returns false if an underlying read error
+  // occurs.
+  bool Skip(int count);
+
+  // Read raw bytes, copying them into the given buffer.
+  bool ReadRaw(void* buffer, int size);
+
+  // Like ReadRaw, but reads into a string.
+  //
+  // Implementation Note:  ReadString() grows the string gradually as it
+  // reads in the data, rather than allocating the entire requested size
+  // upfront.  This prevents denial-of-service attacks in which a client
+  // could claim that a string is going to be MAX_INT bytes long in order to
+  // crash the server because it can't allocate this much space at once.
+  bool ReadString(string* buffer, int size);
+
+
+  // Read a 32-bit little-endian integer.
+  bool ReadLittleEndian32(uint32* value);
+  // Read a 64-bit little-endian integer.
+  bool ReadLittleEndian64(uint64* value);
+
+  // Read an unsigned integer with Varint encoding, truncating to 32 bits.
+  // Reading a 32-bit value is equivalent to reading a 64-bit one and casting
+  // it to uint32, but may be more efficient.
+  bool ReadVarint32(uint32* value);
+  // Read an unsigned integer with Varint encoding.
+  bool ReadVarint64(uint64* value);
+
+  // Read a tag.  This calls ReadVarint32() and returns the result, or returns
+  // zero (which is not a valid tag) if ReadVarint32() fails.  Also, it updates
+  // the last tag value, which can be checked with LastTagWas().
+  // Always inline because this is only called in once place per parse loop
+  // but it is called for every iteration of said loop, so it should be fast.
+  // GCC doesn't want to inline this by default.
+  uint32 ReadTag() GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+  // Usually returns true if calling ReadVarint32() now would produce the given
+  // value.  Will always return false if ReadVarint32() would not return the
+  // given value.  If ExpectTag() returns true, it also advances past
+  // the varint.  For best performance, use a compile-time constant as the
+  // parameter.
+  // Always inline because this collapses to a small number of instructions
+  // when given a constant parameter, but GCC doesn't want to inline by default.
+  bool ExpectTag(uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+  // Usually returns true if no more bytes can be read.  Always returns false
+  // if more bytes can be read.  If ExpectAtEnd() returns true, a subsequent
+  // call to LastTagWas() will act as if ReadTag() had been called and returned
+  // zero, and ConsumedEntireMessage() will return true.
+  bool ExpectAtEnd();
+
+  // If the last call to ReadTag() returned the given value, returns true.
+  // Otherwise, returns false;
+  //
+  // This is needed because parsers for some types of embedded messages
+  // (with field type TYPE_GROUP) don't actually know that they've reached the
+  // end of a message until they see an ENDGROUP tag, which was actually part
+  // of the enclosing message.  The enclosing message would like to check that
+  // tag to make sure it had the right number, so it calls LastTagWas() on
+  // return from the embedded parser to check.
+  bool LastTagWas(uint32 expected);
+
+  // When parsing message (but NOT a group), this method must be called
+  // immediately after MergeFromCodedStream() returns (if it returns true)
+  // to further verify that the message ended in a legitimate way.  For
+  // example, this verifies that parsing did not end on an end-group tag.
+  // It also checks for some cases where, due to optimizations,
+  // MergeFromCodedStream() can incorrectly return true.
+  bool ConsumedEntireMessage();
+
+  // Limits ----------------------------------------------------------
+  // Limits are used when parsing length-delimited embedded messages.
+  // After the message's length is read, PushLimit() is used to prevent
+  // the CodedInputStream from reading beyond that length.  Once the
+  // embedded message has been parsed, PopLimit() is called to undo the
+  // limit.
+
+  // Opaque type used with PushLimit() and PopLimit().  Do not modify
+  // values of this type yourself.  The only reason that this isn't a
+  // struct with private internals is for efficiency.
+  typedef int Limit;
+
+  // Places a limit on the number of bytes that the stream may read,
+  // starting from the current position.  Once the stream hits this limit,
+  // it will act like the end of the input has been reached until PopLimit()
+  // is called.
+  //
+  // As the names imply, the stream conceptually has a stack of limits.  The
+  // shortest limit on the stack is always enforced, even if it is not the
+  // top limit.
+  //
+  // The value returned by PushLimit() is opaque to the caller, and must
+  // be passed unchanged to the corresponding call to PopLimit().
+  Limit PushLimit(int byte_limit);
+
+  // Pops the last limit pushed by PushLimit().  The input must be the value
+  // returned by that call to PushLimit().
+  void PopLimit(Limit limit);
+
+  // Returns the number of bytes left until the nearest limit on the
+  // stack is hit, or -1 if no limits are in place.
+  int BytesUntilLimit();
+
+  // Total Bytes Limit -----------------------------------------------
+  // To prevent malicious users from sending excessively large messages
+  // and causing integer overflows or memory exhaustion, CodedInputStream
+  // imposes a hard limit on the total number of bytes it will read.
+
+  // Sets the maximum number of bytes that this CodedInputStream will read
+  // before refusing to continue.  To prevent integer overflows in the
+  // protocol buffers implementation, as well as to prevent servers from
+  // allocating enormous amounts of memory to hold parsed messages, the
+  // maximum message length should be limited to the shortest length that
+  // will not harm usability.  The theoretical shortest message that could
+  // cause integer overflows is 512MB.  The default limit is 64MB.  Apps
+  // should set shorter limits if possible.  If warning_threshold is not -1,
+  // a warning will be printed to stderr after warning_threshold bytes are
+  // read.  An error will always be printed to stderr if the limit is
+  // reached.
+  //
+  // This is unrelated to PushLimit()/PopLimit().
+  //
+  // Hint:  If you are reading this because your program is printing a
+  //   warning about dangerously large protocol messages, you may be
+  //   confused about what to do next.  The best option is to change your
+  //   design such that excessively large messages are not necessary.
+  //   For example, try to design file formats to consist of many small
+  //   messages rather than a single large one.  If this is infeasible,
+  //   you will need to increase the limit.  Chances are, though, that
+  //   your code never constructs a CodedInputStream on which the limit
+  //   can be set.  You probably parse messages by calling things like
+  //   Message::ParseFromString().  In this case, you will need to change
+  //   your code to instead construct some sort of ZeroCopyInputStream
+  //   (e.g. an ArrayInputStream), construct a CodedInputStream around
+  //   that, then call Message::ParseFromCodedStream() instead.  Then
+  //   you can adjust the limit.  Yes, it's more work, but you're doing
+  //   something unusual.
+  void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold);
+
+  // Recursion Limit -------------------------------------------------
+  // To prevent corrupt or malicious messages from causing stack overflows,
+  // we must keep track of the depth of recursion when parsing embedded
+  // messages and groups.  CodedInputStream keeps track of this because it
+  // is the only object that is passed down the stack during parsing.
+
+  // Sets the maximum recursion depth.  The default is 64.
+  void SetRecursionLimit(int limit);
+
+  // Increments the current recursion depth.  Returns true if the depth is
+  // under the limit, false if it has gone over.
+  bool IncrementRecursionDepth();
+
+  // Decrements the recursion depth.
+  void DecrementRecursionDepth();
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream);
+
+  ZeroCopyInputStream* input_;
+  const uint8* buffer_;
+  int buffer_size_;       // size of current buffer
+  int total_bytes_read_;  // total bytes read from input_, including
+                          // the current buffer
+
+  // If total_bytes_read_ surpasses INT_MAX, we record the extra bytes here
+  // so that we can BackUp() on destruction.
+  int overflow_bytes_;
+
+  // LastTagWas() stuff.
+  uint32 last_tag_;         // result of last ReadTag().
+
+  // This is set true by ReadVarint32Fallback() if it is called when exactly
+  // at EOF, or by ExpectAtEnd() when it returns true.  This happens when we
+  // reach the end of a message and attempt to read another tag.
+  bool legitimate_message_end_;
+
+  // See EnableAliasing().
+  bool aliasing_enabled_;
+
+  // Limits
+  Limit current_limit_;   // if position = -1, no limit is applied
+
+  // For simplicity, if the current buffer crosses a limit (either a normal
+  // limit created by PushLimit() or the total bytes limit), buffer_size_
+  // only tracks the number of bytes before that limit.  This field
+  // contains the number of bytes after it.  Note that this implies that if
+  // buffer_size_ == 0 and buffer_size_after_limit_ > 0, we know we've
+  // hit a limit.  However, if both are zero, it doesn't necessarily mean
+  // we aren't at a limit -- the buffer may have ended exactly at the limit.
+  int buffer_size_after_limit_;
+
+  // Maximum number of bytes to read, period.  This is unrelated to
+  // current_limit_.  Set using SetTotalBytesLimit().
+  int total_bytes_limit_;
+  int total_bytes_warning_threshold_;
+
+  // Current recursion depth, controlled by IncrementRecursionDepth() and
+  // DecrementRecursionDepth().
+  int recursion_depth_;
+  // Recursion depth limit, set by SetRecursionLimit().
+  int recursion_limit_;
+
+  // Advance the buffer by a given number of bytes.
+  void Advance(int amount);
+
+  // Recomputes the value of buffer_size_after_limit_.  Must be called after
+  // current_limit_ or total_bytes_limit_ changes.
+  void RecomputeBufferLimits();
+
+  // Writes an error message saying that we hit total_bytes_limit_.
+  void PrintTotalBytesLimitError();
+
+  // Called when the buffer runs out to request more data.  Implies an
+  // Advance(buffer_size_).
+  bool Refresh();
+
+  bool ReadVarint32Fallback(uint32* value);
+};
+
+// Class which encodes and writes binary data which is composed of varint-
+// encoded integers and fixed-width pieces.  Wraps a ZeroCopyOutputStream.
+// Most users will not need to deal with CodedOutputStream.
+//
+// Most methods of CodedOutputStream which return a bool return false if an
+// underlying I/O error occurs.  Once such a failure occurs, the
+// CodedOutputStream is broken and is no longer useful.
+class LIBPROTOBUF_EXPORT CodedOutputStream {
+ public:
+  // Create an CodedOutputStream that writes to the given ZeroCopyOutputStream.
+  explicit CodedOutputStream(ZeroCopyOutputStream* output);
+
+  // Destroy the CodedOutputStream and position the underlying
+  // ZeroCopyOutputStream immediately after the last byte written.
+  ~CodedOutputStream();
+
+  // Write raw bytes, copying them from the given buffer.
+  bool WriteRaw(const void* buffer, int size);
+
+  // Equivalent to WriteRaw(str.data(), str.size()).
+  bool WriteString(const string& str);
+
+
+  // Write a 32-bit little-endian integer.
+  bool WriteLittleEndian32(uint32 value);
+  // Write a 64-bit little-endian integer.
+  bool WriteLittleEndian64(uint64 value);
+
+  // Write an unsigned integer with Varint encoding.  Writing a 32-bit value
+  // is equivalent to casting it to uint64 and writing it as a 64-bit value,
+  // but may be more efficient.
+  bool WriteVarint32(uint32 value);
+  // Write an unsigned integer with Varint encoding.
+  bool WriteVarint64(uint64 value);
+
+  // Equivalent to WriteVarint32() except when the value is negative,
+  // in which case it must be sign-extended to a full 10 bytes.
+  bool WriteVarint32SignExtended(int32 value);
+
+  // This is identical to WriteVarint32(), but optimized for writing tags.
+  // In particular, if the input is a compile-time constant, this method
+  // compiles down to a couple instructions.
+  // Always inline because otherwise the aformentioned optimization can't work,
+  // but GCC by default doesn't want to inline this.
+  bool WriteTag(uint32 value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+  // Returns the number of bytes needed to encode the given value as a varint.
+  static int VarintSize32(uint32 value);
+  // Returns the number of bytes needed to encode the given value as a varint.
+  static int VarintSize64(uint64 value);
+
+  // If negative, 10 bytes.  Otheriwse, same as VarintSize32().
+  static int VarintSize32SignExtended(int32 value);
+
+  // Returns the total number of bytes written since this object was created.
+  inline int ByteCount() const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream);
+
+  ZeroCopyOutputStream* output_;
+  uint8* buffer_;
+  int buffer_size_;
+  int total_bytes_;  // Sum of sizes of all buffers seen so far.
+
+  // Advance the buffer by a given number of bytes.
+  void Advance(int amount);
+
+  // Called when the buffer runs out to request more data.  Implies an
+  // Advance(buffer_size_).
+  bool Refresh();
+
+  bool WriteVarint32Fallback(uint32 value);
+  static int VarintSize32Fallback(uint32 value);
+};
+
+// inline methods ====================================================
+// The vast majority of varints are only one byte.  These inline
+// methods optimize for that case.
+
+inline bool CodedInputStream::ReadVarint32(uint32* value) {
+  if (buffer_size_ != 0 && *buffer_ < 0x80) {
+    *value = *buffer_;
+    Advance(1);
+    return true;
+  } else {
+    return ReadVarint32Fallback(value);
+  }
+}
+
+inline uint32 CodedInputStream::ReadTag() {
+  if (buffer_size_ != 0 && buffer_[0] < 0x80) {
+    last_tag_ = buffer_[0];
+    Advance(1);
+    return last_tag_;
+  } else if (buffer_size_ >= 2 && buffer_[1] < 0x80) {
+    last_tag_ = (buffer_[0] & 0x7f) + (buffer_[1] << 7);
+    Advance(2);
+    return last_tag_;
+  } else if (ReadVarint32Fallback(&last_tag_)) {
+    return last_tag_;
+  } else {
+    last_tag_ = 0;
+    return 0;
+  }
+}
+
+inline bool CodedInputStream::LastTagWas(uint32 expected) {
+  return last_tag_ == expected;
+}
+
+inline bool CodedInputStream::ConsumedEntireMessage() {
+  return legitimate_message_end_;
+}
+
+inline bool CodedInputStream::ExpectTag(uint32 expected) {
+  if (expected < (1 << 7)) {
+    if (buffer_size_ != 0 && buffer_[0] == expected) {
+      Advance(1);
+      return true;
+    } else {
+      return false;
+    }
+  } else if (expected < (1 << 14)) {
+    if (buffer_size_ >= 2 &&
+        buffer_[0] == static_cast<uint8>(expected | 0x80) &&
+        buffer_[1] == static_cast<uint8>(expected >> 7)) {
+      Advance(2);
+      return true;
+    } else {
+      return false;
+    }
+  } else {
+    // Don't bother optimizing for larger values.
+    return false;
+  }
+}
+
+inline bool CodedInputStream::ExpectAtEnd() {
+  // If we are at a limit we know no more bytes can be read.  Otherwise, it's
+  // hard to say without calling Refresh(), and we'd rather not do that.
+
+  if (buffer_size_ == 0 && buffer_size_after_limit_ != 0) {
+    last_tag_ = 0;                   // Pretend we called ReadTag()...
+    legitimate_message_end_ = true;  // ... and it hit EOF.
+    return true;
+  } else {
+    return false;
+  }
+}
+
+inline bool CodedOutputStream::WriteVarint32(uint32 value) {
+  if (value < 0x80 && buffer_size_ > 0) {
+    *buffer_ = value;
+    Advance(1);
+    return true;
+  } else {
+    return WriteVarint32Fallback(value);
+  }
+}
+
+inline bool CodedOutputStream::WriteVarint32SignExtended(int32 value) {
+  if (value < 0) {
+    return WriteVarint64(static_cast<uint64>(value));
+  } else {
+    return WriteVarint32(static_cast<uint32>(value));
+  }
+}
+
+inline bool CodedOutputStream::WriteTag(uint32 value) {
+  if (value < (1 << 7)) {
+    if (buffer_size_ != 0) {
+      buffer_[0] = value;
+      Advance(1);
+      return true;
+    }
+  } else if (value < (1 << 14)) {
+    if (buffer_size_ >= 2) {
+      buffer_[0] = static_cast<uint8>(value | 0x80);
+      buffer_[1] = static_cast<uint8>(value >> 7);
+      Advance(2);
+      return true;
+    }
+  }
+  return WriteVarint32Fallback(value);
+}
+
+inline int CodedOutputStream::VarintSize32(uint32 value) {
+  if (value < (1 << 7)) {
+    return 1;
+  } else  {
+    return VarintSize32Fallback(value);
+  }
+}
+
+inline int CodedOutputStream::VarintSize32SignExtended(int32 value) {
+  if (value < 0) {
+    return 10;     // TODO(kenton):  Make this a symbolic constant.
+  } else {
+    return VarintSize32(static_cast<uint32>(value));
+  }
+}
+
+inline bool CodedOutputStream::WriteString(const string& str) {
+  return WriteRaw(str.data(), str.size());
+}
+
+inline int CodedOutputStream::ByteCount() const {
+  return total_bytes_ - buffer_size_;
+}
+
+inline void CodedInputStream::Advance(int amount) {
+  buffer_ += amount;
+  buffer_size_ -= amount;
+}
+
+inline void CodedOutputStream::Advance(int amount) {
+  buffer_ += amount;
+  buffer_size_ -= amount;
+}
+
+inline void CodedInputStream::SetRecursionLimit(int limit) {
+  recursion_limit_ = limit;
+}
+
+inline bool CodedInputStream::IncrementRecursionDepth() {
+  ++recursion_depth_;
+  return recursion_depth_ <= recursion_limit_;
+}
+
+inline void CodedInputStream::DecrementRecursionDepth() {
+  if (recursion_depth_ > 0) --recursion_depth_;
+}
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc
new file mode 100644
index 0000000..c1a8834
--- /dev/null
+++ b/src/google/protobuf/io/coded_stream_unittest.cc
@@ -0,0 +1,929 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains tests and benchmarks.
+
+#include <vector>
+
+#include <google/protobuf/io/coded_stream.h>
+
+#include <limits.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/strutil.h>
+
+
+// This declares an unsigned long long integer literal in a portable way.
+// (The original macro is way too big and ruins my formatting.)
+#undef ULL
+#define ULL(x) GOOGLE_ULONGLONG(x)
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+// ===================================================================
+// Data-Driven Test Infrastructure
+
+// TEST_1D and TEST_2D are macros I'd eventually like to see added to
+// gTest.  These macros can be used to declare tests which should be
+// run multiple times, once for each item in some input array.  TEST_1D
+// tests all cases in a single input array.  TEST_2D tests all
+// combinations of cases from two arrays.  The arrays must be statically
+// defined such that the GOOGLE_ARRAYSIZE() macro works on them.  Example:
+//
+// int kCases[] = {1, 2, 3, 4}
+// TEST_1D(MyFixture, MyTest, kCases) {
+//   EXPECT_GT(kCases_case, 0);
+// }
+//
+// This test iterates through the numbers 1, 2, 3, and 4 and tests that
+// they are all grater than zero.  In case of failure, the exact case
+// which failed will be printed.  The case type must be printable using
+// ostream::operator<<.
+
+#define TEST_1D(FIXTURE, NAME, CASES)                                      \
+  class FIXTURE##_##NAME##_DD : public FIXTURE {                           \
+   protected:                                                              \
+    template <typename CaseType>                                           \
+    void DoSingleCase(const CaseType& CASES##_case);                       \
+  };                                                                       \
+                                                                           \
+  TEST_F(FIXTURE##_##NAME##_DD, NAME) {                                    \
+    for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) {                           \
+      SCOPED_TRACE(testing::Message()                                      \
+        << #CASES " case #" << i << ": " << CASES[i]);                     \
+      DoSingleCase(CASES[i]);                                              \
+    }                                                                      \
+  }                                                                        \
+                                                                           \
+  template <typename CaseType>                                             \
+  void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
+
+#define TEST_2D(FIXTURE, NAME, CASES1, CASES2)                             \
+  class FIXTURE##_##NAME##_DD : public FIXTURE {                           \
+   protected:                                                              \
+    template <typename CaseType1, typename CaseType2>                      \
+    void DoSingleCase(const CaseType1& CASES1##_case,                      \
+                      const CaseType2& CASES2##_case);                     \
+  };                                                                       \
+                                                                           \
+  TEST_F(FIXTURE##_##NAME##_DD, NAME) {                                    \
+    for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) {                          \
+      for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) {                        \
+        SCOPED_TRACE(testing::Message()                                    \
+          << #CASES1 " case #" << i << ": " << CASES1[i] << ", "           \
+          << #CASES2 " case #" << j << ": " << CASES2[j]);                 \
+        DoSingleCase(CASES1[i], CASES2[j]);                                \
+      }                                                                    \
+    }                                                                      \
+  }                                                                        \
+                                                                           \
+  template <typename CaseType1, typename CaseType2>                        \
+  void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
+                                           const CaseType2& CASES2##_case)
+
+// ===================================================================
+
+class CodedStreamTest : public testing::Test {
+ protected:
+  static const int kBufferSize = 1024 * 64;
+  static uint8 buffer_[kBufferSize];
+};
+
+uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize];
+
+// We test each operation over a variety of block sizes to insure that
+// we test cases where reads or writes cross buffer boundaries, cases
+// where they don't, and cases where there is so much buffer left that
+// we can use special optimized paths that don't worry about bounds
+// checks.
+const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
+
+// -------------------------------------------------------------------
+// Varint tests.
+
+struct VarintCase {
+  uint8 bytes[10];          // Encoded bytes.
+  int size;                 // Encoded size, in bytes.
+  uint64 value;             // Parsed value.
+};
+
+inline std::ostream& operator<<(std::ostream& os, const VarintCase& c) {
+  return os << c.value;
+}
+
+VarintCase kVarintCases[] = {
+  // 32-bit values
+  {{0x00}      , 1, 0},
+  {{0x01}      , 1, 1},
+  {{0x7f}      , 1, 127},
+  {{0xa2, 0x74}, 2, (0x22 << 0) | (0x74 << 7)},          // 14882
+  {{0xbe, 0xf7, 0x92, 0x84, 0x0b}, 5,                    // 2961488830
+    (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+    (ULL(0x0b) << 28)},
+
+  // 64-bit
+  {{0xbe, 0xf7, 0x92, 0x84, 0x1b}, 5,                    // 7256456126
+    (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+    (ULL(0x1b) << 28)},
+  {{0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49}, 8,  // 41256202580718336
+    (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+    (ULL(0x43) << 28) | (ULL(0x49) << 35) | (ULL(0x24) << 42) |
+    (ULL(0x49) << 49)},
+  // 11964378330978735131
+  {{0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01}, 10,
+    (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+    (ULL(0x3b) << 28) | (ULL(0x56) << 35) | (ULL(0x00) << 42) |
+    (ULL(0x05) << 49) | (ULL(0x26) << 56) | (ULL(0x01) << 63)},
+};
+
+TEST_2D(CodedStreamTest, ReadVarint32, kVarintCases, kBlockSizes) {
+  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    uint32 value;
+    EXPECT_TRUE(coded_input.ReadVarint32(&value));
+    EXPECT_EQ(static_cast<uint32>(kVarintCases_case.value), value);
+  }
+
+  EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) {
+  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
+    EXPECT_EQ(expected_value, coded_input.ReadTag());
+
+    EXPECT_TRUE(coded_input.LastTagWas(expected_value));
+    EXPECT_FALSE(coded_input.LastTagWas(expected_value + 1));
+  }
+
+  EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
+}
+
+TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) {
+  // Leave one byte at the beginning of the buffer so we can read it
+  // to force the first buffer to be loaded.
+  buffer_[0] = '\0';
+  memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size);
+  ArrayInputStream input(buffer_, sizeof(buffer_));
+
+  {
+    CodedInputStream coded_input(&input);
+
+    // Read one byte to force coded_input.Refill() to be called.  Otherwise,
+    // ExpectTag() will return a false negative.
+    uint8 dummy;
+    coded_input.ReadRaw(&dummy, 1);
+    EXPECT_EQ((uint)'\0', (uint)dummy);
+
+    uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
+
+    // ExpectTag() produces false negatives for large values.
+    if (kVarintCases_case.size <= 2) {
+      EXPECT_FALSE(coded_input.ExpectTag(expected_value + 1));
+      EXPECT_TRUE(coded_input.ExpectTag(expected_value));
+    } else {
+      EXPECT_FALSE(coded_input.ExpectTag(expected_value));
+    }
+  }
+
+  if (kVarintCases_case.size <= 2) {
+    EXPECT_EQ(kVarintCases_case.size + 1, input.ByteCount());
+  } else {
+    EXPECT_EQ(1, input.ByteCount());
+  }
+}
+
+TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) {
+  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    uint64 value;
+    EXPECT_TRUE(coded_input.ReadVarint64(&value));
+    EXPECT_EQ(kVarintCases_case.value, value);
+  }
+
+  EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, WriteVarint32, kVarintCases, kBlockSizes) {
+  if (kVarintCases_case.value > ULL(0x00000000FFFFFFFF)) {
+    // Skip this test for the 64-bit values.
+    return;
+  }
+
+  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedOutputStream coded_output(&output);
+
+    EXPECT_TRUE(coded_output.WriteVarint32(
+      static_cast<uint32>(kVarintCases_case.value)));
+
+    EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
+  }
+
+  EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
+  EXPECT_EQ(0,
+    memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
+}
+
+TEST_2D(CodedStreamTest, WriteVarint64, kVarintCases, kBlockSizes) {
+  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedOutputStream coded_output(&output);
+
+    EXPECT_TRUE(coded_output.WriteVarint64(kVarintCases_case.value));
+
+    EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
+  }
+
+  EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
+  EXPECT_EQ(0,
+    memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
+}
+
+// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error:
+//   "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
+#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
+
+int32 kSignExtendedVarintCases[] = {
+  0, 1, -1, 1237894, -37895138
+};
+
+TEST_2D(CodedStreamTest, WriteVarint32SignExtended,
+        kSignExtendedVarintCases, kBlockSizes) {
+  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedOutputStream coded_output(&output);
+
+    EXPECT_TRUE(coded_output.WriteVarint32SignExtended(
+      kSignExtendedVarintCases_case));
+
+    if (kSignExtendedVarintCases_case < 0) {
+      EXPECT_EQ(10, coded_output.ByteCount());
+    } else {
+      EXPECT_LE(coded_output.ByteCount(), 5);
+    }
+  }
+
+  if (kSignExtendedVarintCases_case < 0) {
+    EXPECT_EQ(10, output.ByteCount());
+  } else {
+    EXPECT_LE(output.ByteCount(), 5);
+  }
+
+  // Read value back in as a varint64 and insure it matches.
+  ArrayInputStream input(buffer_, sizeof(buffer_));
+
+  {
+    CodedInputStream coded_input(&input);
+
+    uint64 value;
+    EXPECT_TRUE(coded_input.ReadVarint64(&value));
+
+    EXPECT_EQ(kSignExtendedVarintCases_case, static_cast<int64>(value));
+  }
+
+  EXPECT_EQ(output.ByteCount(), input.ByteCount());
+}
+
+#endif
+
+
+// -------------------------------------------------------------------
+// Varint failure test.
+
+struct VarintErrorCase {
+  uint8 bytes[12];
+  int size;
+  bool can_parse;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const VarintErrorCase& c) {
+  return os << "size " << c.size;
+}
+
+const VarintErrorCase kVarintErrorCases[] = {
+  // Control case.  (Insures that there isn't something else wrong that
+  // makes parsing always fail.)
+  {{0x00}, 1, true},
+
+  // No input data.
+  {{}, 0, false},
+
+  // Input ends unexpectedly.
+  {{0xf0, 0xab}, 2, false},
+
+  // Input ends unexpectedly after 32 bits.
+  {{0xf0, 0xab, 0xc9, 0x9a, 0xf8, 0xb2}, 6, false},
+
+  // Longer than 10 bytes.
+  {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
+   11, false},
+};
+
+TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) {
+  memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
+  ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
+                         kBlockSizes_case);
+  CodedInputStream coded_input(&input);
+
+  uint32 value;
+  EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value));
+}
+
+TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) {
+  memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
+  ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
+                         kBlockSizes_case);
+  CodedInputStream coded_input(&input);
+
+  uint64 value;
+  EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value));
+}
+
+// -------------------------------------------------------------------
+// VarintSize
+
+struct VarintSizeCase {
+  uint64 value;
+  int size;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) {
+  return os << c.value;
+}
+
+VarintSizeCase kVarintSizeCases[] = {
+  {0u, 1},
+  {1u, 1},
+  {127u, 1},
+  {128u, 2},
+  {758923u, 3},
+  {4000000000u, 5},
+  {ULL(41256202580718336), 8},
+  {ULL(11964378330978735131), 10},
+};
+
+TEST_1D(CodedStreamTest, VarintSize32, kVarintSizeCases) {
+  if (kVarintSizeCases_case.value > 0xffffffffu) {
+    // Skip 64-bit values.
+    return;
+  }
+
+  EXPECT_EQ(kVarintSizeCases_case.size,
+    CodedOutputStream::VarintSize32(
+      static_cast<uint32>(kVarintSizeCases_case.value)));
+}
+
+TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) {
+  EXPECT_EQ(kVarintSizeCases_case.size,
+    CodedOutputStream::VarintSize64(kVarintSizeCases_case.value));
+}
+
+// -------------------------------------------------------------------
+// Fixed-size int tests
+
+struct Fixed32Case {
+  uint8 bytes[sizeof(uint32)];          // Encoded bytes.
+  uint32 value;                         // Parsed value.
+};
+
+struct Fixed64Case {
+  uint8 bytes[sizeof(uint64)];          // Encoded bytes.
+  uint64 value;                         // Parsed value.
+};
+
+inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) {
+  return os << "0x" << hex << c.value << dec;
+}
+
+inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) {
+  return os << "0x" << hex << c.value << dec;
+}
+
+Fixed32Case kFixed32Cases[] = {
+  {{0xef, 0xcd, 0xab, 0x90}, 0x90abcdefu},
+  {{0x12, 0x34, 0x56, 0x78}, 0x78563412u},
+};
+
+Fixed64Case kFixed64Cases[] = {
+  {{0xef, 0xcd, 0xab, 0x90, 0x12, 0x34, 0x56, 0x78}, ULL(0x7856341290abcdef)},
+  {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, ULL(0x8877665544332211)},
+};
+
+TEST_2D(CodedStreamTest, ReadLittleEndian32, kFixed32Cases, kBlockSizes) {
+  memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    uint32 value;
+    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(kFixed32Cases_case.value, value);
+  }
+
+  EXPECT_EQ(sizeof(uint32), input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, ReadLittleEndian64, kFixed64Cases, kBlockSizes) {
+  memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    uint64 value;
+    EXPECT_TRUE(coded_input.ReadLittleEndian64(&value));
+    EXPECT_EQ(kFixed64Cases_case.value, value);
+  }
+
+  EXPECT_EQ(sizeof(uint64), input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, WriteLittleEndian32, kFixed32Cases, kBlockSizes) {
+  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedOutputStream coded_output(&output);
+
+    EXPECT_TRUE(coded_output.WriteLittleEndian32(kFixed32Cases_case.value));
+
+    EXPECT_EQ(sizeof(uint32), coded_output.ByteCount());
+  }
+
+  EXPECT_EQ(sizeof(uint32), output.ByteCount());
+  EXPECT_EQ(0, memcmp(buffer_, kFixed32Cases_case.bytes, sizeof(uint32)));
+}
+
+TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) {
+  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedOutputStream coded_output(&output);
+
+    EXPECT_TRUE(coded_output.WriteLittleEndian64(kFixed64Cases_case.value));
+
+    EXPECT_EQ(sizeof(uint64), coded_output.ByteCount());
+  }
+
+  EXPECT_EQ(sizeof(uint64), output.ByteCount());
+  EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64)));
+}
+
+// -------------------------------------------------------------------
+// Raw reads and writes
+
+const char kRawBytes[] = "Some bytes which will be writted and read raw.";
+
+TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+  char read_buffer[sizeof(kRawBytes)];
+
+  {
+    CodedInputStream coded_input(&input);
+
+    EXPECT_TRUE(coded_input.ReadRaw(read_buffer, sizeof(kRawBytes)));
+    EXPECT_EQ(0, memcmp(kRawBytes, read_buffer, sizeof(kRawBytes)));
+  }
+
+  EXPECT_EQ(sizeof(kRawBytes), input.ByteCount());
+}
+
+TEST_1D(CodedStreamTest, WriteRaw, kBlockSizes) {
+  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedOutputStream coded_output(&output);
+
+    EXPECT_TRUE(coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes)));
+
+    EXPECT_EQ(sizeof(kRawBytes), coded_output.ByteCount());
+  }
+
+  EXPECT_EQ(sizeof(kRawBytes), output.ByteCount());
+  EXPECT_EQ(0, memcmp(buffer_, kRawBytes, sizeof(kRawBytes)));
+}
+
+TEST_1D(CodedStreamTest, ReadString, kBlockSizes) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    string str;
+    EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+    EXPECT_EQ(kRawBytes, str);
+  }
+
+  EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+// Check to make sure ReadString doesn't crash on impossibly large strings.
+TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) {
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    string str;
+    // Try to read a gigabyte.
+    EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+  }
+}
+
+
+// -------------------------------------------------------------------
+// Skip
+
+const char kSkipTestBytes[] =
+  "<Before skipping><To be skipped><After skipping>";
+const char kSkipOutputTestBytes[] =
+  "-----------------<To be skipped>----------------";
+
+TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) {
+  memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes));
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    string str;
+    EXPECT_TRUE(coded_input.ReadString(&str, strlen("<Before skipping>")));
+    EXPECT_EQ("<Before skipping>", str);
+    EXPECT_TRUE(coded_input.Skip(strlen("<To be skipped>")));
+    EXPECT_TRUE(coded_input.ReadString(&str, strlen("<After skipping>")));
+    EXPECT_EQ("<After skipping>", str);
+  }
+
+  EXPECT_EQ(strlen(kSkipTestBytes), input.ByteCount());
+}
+
+// -------------------------------------------------------------------
+// Limits
+
+TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) {
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+    CodedInputStream::Limit limit = coded_input.PushLimit(8);
+
+    // Read until we hit the limit.
+    uint32 value;
+    EXPECT_EQ(8, coded_input.BytesUntilLimit());
+    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(4, coded_input.BytesUntilLimit());
+    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(0, coded_input.BytesUntilLimit());
+    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+    coded_input.PopLimit(limit);
+
+    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+  }
+
+  EXPECT_EQ(12, input.ByteCount());
+}
+
+// Test what happens when we push two limits where the second (top) one is
+// shorter.
+TEST_1D(CodedStreamTest, SmallLimitOnTopOfBigLimit, kBlockSizes) {
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+    CodedInputStream::Limit limit1 = coded_input.PushLimit(8);
+    EXPECT_EQ(8, coded_input.BytesUntilLimit());
+    CodedInputStream::Limit limit2 = coded_input.PushLimit(4);
+
+    uint32 value;
+
+    // Read until we hit limit2, the top and shortest limit.
+    EXPECT_EQ(4, coded_input.BytesUntilLimit());
+    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(0, coded_input.BytesUntilLimit());
+    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+    coded_input.PopLimit(limit2);
+
+    // Read until we hit limit1.
+    EXPECT_EQ(4, coded_input.BytesUntilLimit());
+    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(0, coded_input.BytesUntilLimit());
+    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+    coded_input.PopLimit(limit1);
+
+    // No more limits.
+    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+  }
+
+  EXPECT_EQ(12, input.ByteCount());
+}
+
+// Test what happens when we push two limits where the second (top) one is
+// longer.  In this case, the top limit is shortened to match the previous
+// limit.
+TEST_1D(CodedStreamTest, BigLimitOnTopOfSmallLimit, kBlockSizes) {
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+    CodedInputStream::Limit limit1 = coded_input.PushLimit(4);
+    EXPECT_EQ(4, coded_input.BytesUntilLimit());
+    CodedInputStream::Limit limit2 = coded_input.PushLimit(8);
+
+    uint32 value;
+
+    // Read until we hit limit2.  Except, wait!  limit1 is shorter, so
+    // we end up hitting that first, despite having 4 bytes to go on
+    // limit2.
+    EXPECT_EQ(4, coded_input.BytesUntilLimit());
+    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(0, coded_input.BytesUntilLimit());
+    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+    coded_input.PopLimit(limit2);
+
+    // OK, popped limit2, now limit1 is on top, which we've already hit.
+    EXPECT_EQ(0, coded_input.BytesUntilLimit());
+    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+    EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+    coded_input.PopLimit(limit1);
+
+    // No more limits.
+    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+  }
+
+  EXPECT_EQ(8, input.ByteCount());
+}
+
+TEST_F(CodedStreamTest, ExpectAtEnd) {
+  // Test ExpectAtEnd(), which is based on limits.
+  ArrayInputStream input(buffer_, sizeof(buffer_));
+  CodedInputStream coded_input(&input);
+
+  EXPECT_FALSE(coded_input.ExpectAtEnd());
+
+  CodedInputStream::Limit limit = coded_input.PushLimit(4);
+
+  uint32 value;
+  EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+  EXPECT_TRUE(coded_input.ExpectAtEnd());
+
+  coded_input.PopLimit(limit);
+  EXPECT_FALSE(coded_input.ExpectAtEnd());
+}
+
+TEST_F(CodedStreamTest, NegativeLimit) {
+  // Check what happens when we push a negative limit.
+  ArrayInputStream input(buffer_, sizeof(buffer_));
+  CodedInputStream coded_input(&input);
+
+  CodedInputStream::Limit limit = coded_input.PushLimit(-1234);
+  // BytesUntilLimit() returns -1 to mean "no limit", which actually means
+  // "the limit is INT_MAX relative to the beginning of the stream".
+  EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+  coded_input.PopLimit(limit);
+}
+
+TEST_F(CodedStreamTest, NegativeLimitAfterReading) {
+  // Check what happens when we push a negative limit.
+  ArrayInputStream input(buffer_, sizeof(buffer_));
+  CodedInputStream coded_input(&input);
+  ASSERT_TRUE(coded_input.Skip(128));
+
+  CodedInputStream::Limit limit = coded_input.PushLimit(-64);
+  // BytesUntilLimit() returns -1 to mean "no limit", which actually means
+  // "the limit is INT_MAX relative to the beginning of the stream".
+  EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+  coded_input.PopLimit(limit);
+}
+
+TEST_F(CodedStreamTest, OverflowLimit) {
+  // Check what happens when we push a limit large enough that its absolute
+  // position is more than 2GB into the stream.
+  ArrayInputStream input(buffer_, sizeof(buffer_));
+  CodedInputStream coded_input(&input);
+  ASSERT_TRUE(coded_input.Skip(128));
+
+  CodedInputStream::Limit limit = coded_input.PushLimit(INT_MAX);
+  // BytesUntilLimit() returns -1 to mean "no limit", which actually means
+  // "the limit is INT_MAX relative to the beginning of the stream".
+  EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+  coded_input.PopLimit(limit);
+}
+
+TEST_F(CodedStreamTest, TotalBytesLimit) {
+  ArrayInputStream input(buffer_, sizeof(buffer_));
+  CodedInputStream coded_input(&input);
+  coded_input.SetTotalBytesLimit(16, -1);
+
+  string str;
+  EXPECT_TRUE(coded_input.ReadString(&str, 16));
+
+  vector<string> errors;
+
+  {
+    ScopedMemoryLog error_log;
+    EXPECT_FALSE(coded_input.ReadString(&str, 1));
+    errors = error_log.GetMessages(ERROR);
+  }
+
+  ASSERT_EQ(1, errors.size());
+  EXPECT_PRED_FORMAT2(testing::IsSubstring,
+    "A protocol message was rejected because it was too big", errors[0]);
+
+  coded_input.SetTotalBytesLimit(32, -1);
+  EXPECT_TRUE(coded_input.ReadString(&str, 16));
+}
+
+TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) {
+  // total_bytes_limit_ is not a valid place for a message to end.
+
+  ArrayInputStream input(buffer_, sizeof(buffer_));
+  CodedInputStream coded_input(&input);
+
+  // Set both total_bytes_limit and a regular limit at 16 bytes.
+  coded_input.SetTotalBytesLimit(16, -1);
+  CodedInputStream::Limit limit = coded_input.PushLimit(16);
+
+  // Read 16 bytes.
+  string str;
+  EXPECT_TRUE(coded_input.ReadString(&str, 16));
+
+  // Read a tag.  Should fail, but report being a valid endpoint since it's
+  // a regular limit.
+  EXPECT_EQ(0, coded_input.ReadTag());
+  EXPECT_TRUE(coded_input.ConsumedEntireMessage());
+
+  // Pop the limit.
+  coded_input.PopLimit(limit);
+
+  // Read a tag.  Should fail, and report *not* being a valid endpoint, since
+  // this time we're hitting the total bytes limit.
+  EXPECT_EQ(0, coded_input.ReadTag());
+  EXPECT_FALSE(coded_input.ConsumedEntireMessage());
+}
+
+TEST_F(CodedStreamTest, RecursionLimit) {
+  ArrayInputStream input(buffer_, sizeof(buffer_));
+  CodedInputStream coded_input(&input);
+  coded_input.SetRecursionLimit(4);
+
+  // This is way too much testing for a counter.
+  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 1
+  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 2
+  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 3
+  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
+  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
+  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 6
+  coded_input.DecrementRecursionDepth();                   // 5
+  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 6
+  coded_input.DecrementRecursionDepth();                   // 5
+  coded_input.DecrementRecursionDepth();                   // 4
+  coded_input.DecrementRecursionDepth();                   // 3
+  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
+  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
+  coded_input.DecrementRecursionDepth();                   // 4
+  coded_input.DecrementRecursionDepth();                   // 3
+  coded_input.DecrementRecursionDepth();                   // 2
+  coded_input.DecrementRecursionDepth();                   // 1
+  coded_input.DecrementRecursionDepth();                   // 0
+  coded_input.DecrementRecursionDepth();                   // 0
+  coded_input.DecrementRecursionDepth();                   // 0
+  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 1
+  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 2
+  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 3
+  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
+  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
+
+  coded_input.SetRecursionLimit(6);
+  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 6
+  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 7
+}
+
+class ReallyBigInputStream : public ZeroCopyInputStream {
+ public:
+  ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {}
+  ~ReallyBigInputStream() {}
+
+  // implements ZeroCopyInputStream ----------------------------------
+  bool Next(const void** data, int* size) {
+    // We only expect BackUp() to be called at the end.
+    EXPECT_EQ(0, backup_amount_);
+
+    switch (buffer_count_++) {
+      case 0:
+        *data = buffer_;
+        *size = sizeof(buffer_);
+        return true;
+      case 1:
+        // Return an enormously large buffer that, when combined with the 1k
+        // returned already, should overflow the total_bytes_read_ counter in
+        // CodedInputStream.  Note that we'll only read the first 1024 bytes
+        // of this buffer so it's OK that we have it point at buffer_.
+        *data = buffer_;
+        *size = INT_MAX;
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  void BackUp(int count) {
+    backup_amount_ = count;
+  }
+
+  bool Skip(int count)    { GOOGLE_LOG(FATAL) << "Not implemented."; return false; }
+  int64 ByteCount() const { GOOGLE_LOG(FATAL) << "Not implemented."; return 0; }
+
+  int backup_amount_;
+
+ private:
+  char buffer_[1024];
+  int64 buffer_count_;
+};
+
+TEST_F(CodedStreamTest, InputOver2G) {
+  // CodedInputStream should gracefully handle input over 2G and call
+  // input.BackUp() with the correct number of bytes on destruction.
+  ReallyBigInputStream input;
+
+  vector<string> errors;
+
+  {
+    ScopedMemoryLog error_log;
+    CodedInputStream coded_input(&input);
+    string str;
+    EXPECT_TRUE(coded_input.ReadString(&str, 512));
+    EXPECT_TRUE(coded_input.ReadString(&str, 1024));
+    errors = error_log.GetMessages(ERROR);
+  }
+
+  EXPECT_EQ(INT_MAX - 512, input.backup_amount_);
+  EXPECT_EQ(0, errors.size());
+}
+
+// ===================================================================
+
+
+}  // namespace
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/io/package_info.h b/src/google/protobuf/io/package_info.h
new file mode 100644
index 0000000..8272d51
--- /dev/null
+++ b/src/google/protobuf/io/package_info.h
@@ -0,0 +1,40 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file exists solely to document the google::protobuf::io namespace.
+// It is not compiled into anything, but it may be read by an automated
+// documentation generator.
+
+namespace google {
+
+namespace protobuf {
+
+// Auxiliary classes used for I/O.
+//
+// The Protocol Buffer library uses the classes in this package to deal with
+// I/O and encoding/decoding raw bytes.  Most users will not need to
+// deal with this package.  However, users who want to adapt the system to
+// work with their own I/O abstractions -- e.g., to allow Protocol Buffers
+// to be read from a different kind of input stream without the need for a
+// temporary buffer -- should take a closer look.
+namespace io {}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc
new file mode 100644
index 0000000..7b3e3de
--- /dev/null
+++ b/src/google/protobuf/io/printer.cc
@@ -0,0 +1,165 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter)
+  : variable_delimiter_(variable_delimiter),
+    output_(output),
+    buffer_(NULL),
+    buffer_size_(0),
+    at_start_of_line_(true),
+    failed_(false) {
+}
+
+Printer::~Printer() {
+  // Only BackUp() if we're sure we've successfully called Next() at least once.
+  if (buffer_size_ > 0) {
+    output_->BackUp(buffer_size_);
+  }
+}
+
+void Printer::Print(const map<string, string>& variables, const char* text) {
+  int size = strlen(text);
+  int pos = 0;  // The number of bytes we've written so far.
+
+  for (int i = 0; i < size; i++) {
+    if (text[i] == '\n') {
+      // Saw newline.  If there is more text, we may need to insert an indent
+      // here.  So, write what we have so far, including the '\n'.
+      Write(text + pos, i - pos + 1);
+      pos = i + 1;
+
+      // Setting this true will cause the next Write() to insert an indent
+      // first.
+      at_start_of_line_ = true;
+
+    } else if (text[i] == variable_delimiter_) {
+      // Saw the start of a variable name.
+
+      // Write what we have so far.
+      Write(text + pos, i - pos);
+      pos = i + 1;
+
+      // Find closing delimiter.
+      const char* end = strchr(text + pos, variable_delimiter_);
+      if (end == NULL) {
+        GOOGLE_LOG(DFATAL) << " Unclosed variable name.";
+        end = text + pos;
+      }
+      int endpos = end - text;
+
+      string varname(text + pos, endpos - pos);
+      if (varname.empty()) {
+        // Two delimiters in a row reduce to a literal delimiter character.
+        Write(&variable_delimiter_, 1);
+      } else {
+        // Replace with the variable's value.
+        map<string, string>::const_iterator iter = variables.find(varname);
+        if (iter == variables.end()) {
+          GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname;
+        } else {
+          Write(iter->second.data(), iter->second.size());
+        }
+      }
+
+      // Advance past this variable.
+      i = endpos;
+      pos = endpos + 1;
+    }
+  }
+
+  // Write the rest.
+  Write(text + pos, size - pos);
+}
+
+void Printer::Print(const char* text) {
+  static map<string, string> empty;
+  Print(empty, text);
+}
+
+void Printer::Print(const char* text,
+                    const char* variable, const string& value) {
+  map<string, string> vars;
+  vars[variable] = value;
+  Print(vars, text);
+}
+
+void Printer::Print(const char* text,
+                    const char* variable1, const string& value1,
+                    const char* variable2, const string& value2) {
+  map<string, string> vars;
+  vars[variable1] = value1;
+  vars[variable2] = value2;
+  Print(vars, text);
+}
+
+void Printer::Indent() {
+  indent_ += "  ";
+}
+
+void Printer::Outdent() {
+  if (indent_.empty()) {
+    GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
+    return;
+  }
+
+  indent_.resize(indent_.size() - 2);
+}
+
+void Printer::Write(const char* data, int size) {
+  if (failed_) return;
+  if (size == 0) return;
+
+  if (at_start_of_line_) {
+    // Insert an indent.
+    at_start_of_line_ = false;
+    Write(indent_.data(), indent_.size());
+    if (failed_) return;
+  }
+
+  while (size > buffer_size_) {
+    // Data exceeds space in the buffer.  Copy what we can and request a
+    // new buffer.
+    memcpy(buffer_, data, buffer_size_);
+    data += buffer_size_;
+    size -= buffer_size_;
+    void* void_buffer;
+    failed_ = !output_->Next(&void_buffer, &buffer_size_);
+    if (failed_) return;
+    buffer_ = reinterpret_cast<char*>(void_buffer);
+  }
+
+  // Buffer is big enough to receive the data; copy it.
+  memcpy(buffer_, data, size);
+  buffer_ += size;
+  buffer_size_ -= size;
+}
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h
new file mode 100644
index 0000000..ee8f46c
--- /dev/null
+++ b/src/google/protobuf/io/printer.h
@@ -0,0 +1,109 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Utility class for writing text to a ZeroCopyOutputStream.
+
+#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__
+#define GOOGLE_PROTOBUF_IO_PRINTER_H__
+
+#include <string>
+#include <map>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+class ZeroCopyOutputStream;     // zero_copy_stream.h
+
+// This simple utility class assists in code generation.  It basically
+// allows the caller to define a set of variables and then output some
+// text with variable substitutions.  Example usage:
+//
+//   Printer printer(output, '$');
+//   map<string, string> vars;
+//   vars["name"] = "Bob";
+//   printer.Print(vars, "My name is $name$.");
+//
+// The above writes "My name is Bob." to the output stream.
+//
+// Printer aggressively enforces correct usage, crashing (with assert failures)
+// in the case of undefined variables.  This helps greatly in debugging code
+// which uses it.  This class is not intended to be used by production servers.
+class LIBPROTOBUF_EXPORT Printer {
+ public:
+  // Create a printer that writes text to the given output stream.  Use the
+  // given character as the delimiter for variables.
+  Printer(ZeroCopyOutputStream* output, char variable_delimiter);
+  ~Printer();
+
+  // Print some text after applying variable substitutions.  If a particular
+  // variable in the text is not defined, this will crash.  Variables to be
+  // substituted are identified by their names surrounded by delimiter
+  // characters (as given to the constructor).  The variable bindings are
+  // defined by the given map.
+  void Print(const map<string, string>& variables, const char* text);
+
+  // Like the first Print(), except the substitutions are given as parameters.
+  void Print(const char* text);
+  // Like the first Print(), except the substitutions are given as parameters.
+  void Print(const char* text, const char* variable, const string& value);
+  // Like the first Print(), except the substitutions are given as parameters.
+  void Print(const char* text, const char* variable1, const string& value1,
+                               const char* variable2, const string& value2);
+  // TODO(kenton):  Overloaded versions with more variables?  Two seems
+  //   to be enough.
+
+  // Indent text by two spaces.  After calling Indent(), two spaces will be
+  // inserted at the beginning of each line of text.  Indent() may be called
+  // multiple times to produce deeper indents.
+  void Indent();
+
+  // Reduces the current indent level by two spaces, or crashes if the indent
+  // level is zero.
+  void Outdent();
+
+  // True if any write to the underlying stream failed.  (We don't just
+  // crash in this case because this is an I/O failure, not a programming
+  // error.)
+  bool failed() const { return failed_; }
+
+ private:
+  // Write some text to the output buffer.
+  void Write(const char* data, int size);
+
+  const char variable_delimiter_;
+
+  ZeroCopyOutputStream* const output_;
+  char* buffer_;
+  int buffer_size_;
+
+  string indent_;
+  bool at_start_of_line_;
+  bool failed_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer);
+};
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_PRINTER_H__
diff --git a/src/google/protobuf/io/printer_unittest.cc b/src/google/protobuf/io/printer_unittest.cc
new file mode 100644
index 0000000..652728b
--- /dev/null
+++ b/src/google/protobuf/io/printer_unittest.cc
@@ -0,0 +1,210 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <vector>
+
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+// Each test repeats over several block sizes in order to test both cases
+// where particular writes cross a buffer boundary and cases where they do
+// not.
+
+TEST(Printer, EmptyPrinter) {
+  char buffer[8192];
+  const int block_size = 100;
+  ArrayOutputStream output(buffer, GOOGLE_ARRAYSIZE(buffer), block_size);
+  Printer printer(&output, '\0');
+  EXPECT_TRUE(!printer.failed());
+}
+
+TEST(Printer, BasicPrinting) {
+  char buffer[8192];
+
+  for (int block_size = 1; block_size < 512; block_size *= 2) {
+    ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+    {
+      Printer printer(&output, '\0');
+
+      printer.Print("Hello World!");
+      printer.Print("  This is the same line.\n");
+      printer.Print("But this is a new one.\nAnd this is another one.");
+
+      EXPECT_FALSE(printer.failed());
+    }
+
+    buffer[output.ByteCount()] = '\0';
+
+    EXPECT_STREQ(buffer,
+      "Hello World!  This is the same line.\n"
+      "But this is a new one.\n"
+      "And this is another one.");
+  }
+}
+
+TEST(Printer, VariableSubstitution) {
+  char buffer[8192];
+
+  for (int block_size = 1; block_size < 512; block_size *= 2) {
+    ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+    {
+      Printer printer(&output, '$');
+      map<string, string> vars;
+
+      vars["foo"] = "World";
+      vars["bar"] = "$foo$";
+      vars["abcdefg"] = "1234";
+
+      printer.Print(vars, "Hello $foo$!\nbar = $bar$\n");
+      printer.Print(vars, "$abcdefg$\nA literal dollar sign:  $$");
+
+      vars["foo"] = "blah";
+      printer.Print(vars, "\nNow foo = $foo$.");
+
+      EXPECT_FALSE(printer.failed());
+    }
+
+    buffer[output.ByteCount()] = '\0';
+
+    EXPECT_STREQ(buffer,
+      "Hello World!\n"
+      "bar = $foo$\n"
+      "1234\n"
+      "A literal dollar sign:  $\n"
+      "Now foo = blah.");
+  }
+}
+
+TEST(Printer, InlineVariableSubstitution) {
+  char buffer[8192];
+
+  ArrayOutputStream output(buffer, sizeof(buffer));
+
+  {
+    Printer printer(&output, '$');
+    printer.Print("Hello $foo$!\n", "foo", "World");
+    printer.Print("$foo$ $bar$\n", "foo", "one", "bar", "two");
+    EXPECT_FALSE(printer.failed());
+  }
+
+  buffer[output.ByteCount()] = '\0';
+
+  EXPECT_STREQ(buffer,
+    "Hello World!\n"
+    "one two\n");
+}
+
+TEST(Printer, Indenting) {
+  char buffer[8192];
+
+  for (int block_size = 1; block_size < 512; block_size *= 2) {
+    ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+    {
+      Printer printer(&output, '$');
+      map<string, string> vars;
+
+      vars["newline"] = "\n";
+
+      printer.Print("This is not indented.\n");
+      printer.Indent();
+      printer.Print("This is indented\nAnd so is this\n");
+      printer.Outdent();
+      printer.Print("But this is not.");
+      printer.Indent();
+      printer.Print("  And this is still the same line.\n"
+                    "But this is indented.\n");
+      printer.Print(vars, "Note that a newline in a variable will break "
+                    "indenting, as we see$newline$here.\n");
+      printer.Indent();
+      printer.Print("And this");
+      printer.Outdent();
+      printer.Outdent();
+      printer.Print(" is double-indented\nBack to normal.");
+
+      EXPECT_FALSE(printer.failed());
+    }
+
+    buffer[output.ByteCount()] = '\0';
+
+    EXPECT_STREQ(buffer,
+      "This is not indented.\n"
+      "  This is indented\n"
+      "  And so is this\n"
+      "But this is not.  And this is still the same line.\n"
+      "  But this is indented.\n"
+      "  Note that a newline in a variable will break indenting, as we see\n"
+      "here.\n"
+      "    And this is double-indented\n"
+      "Back to normal.");
+  }
+}
+
+// Death tests do not work on Windows as of yet.
+#ifdef GTEST_HAS_DEATH_TEST
+TEST(Printer, Death) {
+  char buffer[8192];
+
+  ArrayOutputStream output(buffer, sizeof(buffer));
+  Printer printer(&output, '$');
+
+  EXPECT_DEBUG_DEATH(printer.Print("$nosuchvar$"), "Undefined variable");
+  EXPECT_DEBUG_DEATH(printer.Print("$unclosed"), "Unclosed variable name");
+  EXPECT_DEBUG_DEATH(printer.Outdent(), "without matching Indent");
+}
+#endif  // GTEST_HAS_DEATH_TEST
+
+TEST(Printer, WriteFailure) {
+  char buffer[16];
+
+  ArrayOutputStream output(buffer, sizeof(buffer));
+  Printer printer(&output, '$');
+
+  // Print 16 bytes to fill the buffer exactly (should not fail).
+  printer.Print("0123456789abcdef");
+  EXPECT_FALSE(printer.failed());
+
+  // Try to print one more byte (should fail).
+  printer.Print(" ");
+  EXPECT_TRUE(printer.failed());
+
+  // Should not crash
+  printer.Print("blah");
+  EXPECT_TRUE(printer.failed());
+
+  // Buffer should contain the first 16 bytes written.
+  EXPECT_EQ("0123456789abcdef", string(buffer, sizeof(buffer)));
+}
+
+}  // namespace
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc
new file mode 100644
index 0000000..3864fcf
--- /dev/null
+++ b/src/google/protobuf/io/tokenizer.cc
@@ -0,0 +1,679 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Here we have a hand-written lexer.  At first you might ask yourself,
+// "Hand-written text processing?  Is Kenton crazy?!"  Well, first of all,
+// yes I am crazy, but that's beside the point.  There are actually reasons
+// why I ended up writing this this way.
+//
+// The traditional approach to lexing is to use lex to generate a lexer for
+// you.  Unfortunately, lex's output is ridiculously ugly and difficult to
+// integrate cleanly with C++ code, especially abstract code or code meant
+// as a library.  Better parser-generators exist but would add dependencies
+// which most users won't already have, which we'd like to avoid.  (GNU flex
+// has a C++ output option, but it's still ridiculously ugly, non-abstract,
+// and not library-friendly.)
+//
+// The next approach that any good software engineer should look at is to
+// use regular expressions.  And, indeed, I did.  I have code which
+// implements this same class using regular expressions.  It's about 200
+// lines shorter.  However:
+// - Rather than error messages telling you "This string has an invalid
+//   escape sequence at line 5, column 45", you get error messages like
+//   "Parse error on line 5".  Giving more precise errors requires adding
+//   a lot of code that ends up basically as complex as the hand-coded
+//   version anyway.
+// - The regular expression to match a string literal looks like this:
+//     kString  = new RE("(\"([^\"\\\\]|"              // non-escaped
+//                       "\\\\[abfnrtv?\"'\\\\0-7]|"   // normal escape
+//                       "\\\\x[0-9a-fA-F])*\"|"       // hex escape
+//                       "\'([^\'\\\\]|"        // Also support single-quotes.
+//                       "\\\\[abfnrtv?\"'\\\\0-7]|"
+//                       "\\\\x[0-9a-fA-F])*\')");
+//   Verifying the correctness of this line noise is actually harder than
+//   verifying the correctness of ConsumeString(), defined below.  I'm not
+//   even confident that the above is correct, after staring at it for some
+//   time.
+// - PCRE is fast, but there's still more overhead involved than the code
+//   below.
+// - Sadly, regular expressions are not part of the C standard library, so
+//   using them would require depending on some other library.  For the
+//   open source release, this could be really annoying.  Nobody likes
+//   downloading one piece of software just to find that they need to
+//   download something else to make it work, and in all likelihood
+//   people downloading Protocol Buffers will already be doing so just
+//   to make something else work.  We could include a copy of PCRE with
+//   our code, but that obligates us to keep it up-to-date and just seems
+//   like a big waste just to save 200 lines of code.
+//
+// On a similar but unrelated note, I'm even scared to use ctype.h.
+// Apparently functions like isalpha() are locale-dependent.  So, if we used
+// that, then if this code is being called from some program that doesn't
+// have its locale set to "C", it would behave strangely.  We can't just set
+// the locale to "C" ourselves since we might break the calling program that
+// way, particularly if it is multi-threaded.  WTF?  Someone please let me
+// (Kenton) know if I'm missing something here...
+//
+// I'd love to hear about other alternatives, though, as this code isn't
+// exactly pretty.
+
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+// As mentioned above, I don't trust ctype.h due to the presence of "locales".
+// So, I have written replacement functions here.  Someone please smack me if
+// this is a bad idea or if there is some way around this.
+//
+// These "character classes" are designed to be used in template methods.
+// For instance, Tokenizer::ConsumeZeroOrMore<Whitespace>() will eat
+// whitespace.
+
+// Note:  No class is allowed to contain '\0', since this is used to mark end-
+//   of-input and is handled specially.
+
+#define CHARACTER_CLASS(NAME, EXPRESSION)      \
+  class NAME {                                 \
+   public:                                     \
+    static inline bool InClass(char c) {       \
+      return EXPRESSION;                       \
+    }                                          \
+  }
+
+CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' ||
+                            c == '\r' || c == '\v');
+
+CHARACTER_CLASS(Unprintable, c < ' ' && c != '\0');
+
+CHARACTER_CLASS(Digit, '0' <= c && c <= '9');
+CHARACTER_CLASS(OctalDigit, '0' <= c && c <= '7');
+CHARACTER_CLASS(HexDigit, ('0' <= c && c <= '9') ||
+                          ('a' <= c && c <= 'f') ||
+                          ('A' <= c && c <= 'F'));
+
+CHARACTER_CLASS(Letter, ('a' <= c && c <= 'z') ||
+                        ('A' <= c && c <= 'Z') ||
+                        (c == '_'));
+
+CHARACTER_CLASS(Alphanumeric, ('a' <= c && c <= 'z') ||
+                              ('A' <= c && c <= 'Z') ||
+                              ('0' <= c && c <= '9') ||
+                              (c == '_'));
+
+CHARACTER_CLASS(Escape, c == 'a' || c == 'b' || c == 'f' || c == 'n' ||
+                        c == 'r' || c == 't' || c == 'v' || c == '\\' ||
+                        c == '?' || c == '\'' || c == '\"');
+
+#undef CHARACTER_CLASS
+
+// Given a char, interpret it as a numeric digit and return its value.
+// This supports any number base up to 36.
+inline int DigitValue(char digit) {
+  if ('0' <= digit && digit <= '9') return digit - '0';
+  if ('a' <= digit && digit <= 'z') return digit - 'a' + 10;
+  if ('A' <= digit && digit <= 'Z') return digit - 'A' + 10;
+  return -1;
+}
+
+// Inline because it's only used in one place.
+inline char TranslateEscape(char c) {
+  switch (c) {
+    case 'a':  return '\a';
+    case 'b':  return '\b';
+    case 'f':  return '\f';
+    case 'n':  return '\n';
+    case 'r':  return '\r';
+    case 't':  return '\t';
+    case 'v':  return '\v';
+    case '\\': return '\\';
+    case '?':  return '\?';    // Trigraphs = :(
+    case '\'': return '\'';
+    case '"':  return '\"';
+
+    // We expect escape sequences to have been validated separately.
+    default:   return '?';
+  }
+}
+
+}  // anonymous namespace
+
+ErrorCollector::~ErrorCollector() {}
+
+// ===================================================================
+
+Tokenizer::Tokenizer(ZeroCopyInputStream* input,
+                     ErrorCollector* error_collector)
+  : input_(input),
+    error_collector_(error_collector),
+    buffer_(NULL),
+    buffer_size_(0),
+    buffer_pos_(0),
+    read_error_(false),
+    line_(0),
+    column_(0),
+    token_start_(-1),
+    allow_f_after_float_(false),
+    comment_style_(CPP_COMMENT_STYLE) {
+
+  current_.line = 0;
+  current_.column = 0;
+  current_.type = TYPE_START;
+
+  Refresh();
+}
+
+Tokenizer::~Tokenizer() {
+  // If we had any buffer left unread, return it to the underlying stream
+  // so that someone else can read it.
+  if (buffer_size_ > buffer_pos_) {
+    input_->BackUp(buffer_size_ - buffer_pos_);
+  }
+}
+
+// -------------------------------------------------------------------
+// Internal helpers.
+
+void Tokenizer::NextChar() {
+  // Update our line and column counters based on the character being
+  // consumed.
+  if (current_char_ == '\n') {
+    ++line_;
+    column_ = 0;
+  } else if (current_char_ == '\t') {
+    column_ += kTabWidth - column_ % kTabWidth;
+  } else {
+    ++column_;
+  }
+
+  // Advance to the next character.
+  ++buffer_pos_;
+  if (buffer_pos_ < buffer_size_) {
+    current_char_ = buffer_[buffer_pos_];
+  } else {
+    Refresh();
+  }
+}
+
+void Tokenizer::Refresh() {
+  if (read_error_) {
+    current_char_ = '\0';
+    return;
+  }
+
+  // If we're in a token, append the rest of the buffer to it.
+  if (token_start_ >= 0 && token_start_ < buffer_size_) {
+    current_.text.append(buffer_ + token_start_, buffer_size_ - token_start_);
+    token_start_ = 0;
+  }
+
+  const void* data = NULL;
+  buffer_ = NULL;
+  buffer_pos_ = 0;
+  do {
+    if (!input_->Next(&data, &buffer_size_)) {
+      // end of stream (or read error)
+      buffer_size_ = 0;
+      read_error_ = true;
+      current_char_ = '\0';
+      return;
+    }
+  } while (buffer_size_ == 0);
+
+  buffer_ = static_cast<const char*>(data);
+
+  current_char_ = buffer_[0];
+}
+
+inline void Tokenizer::StartToken() {
+  token_start_ = buffer_pos_;
+  current_.type = TYPE_START;    // Just for the sake of initializing it.
+  current_.text.clear();
+  current_.line = line_;
+  current_.column = column_;
+}
+
+inline void Tokenizer::EndToken() {
+  // Note:  The if() is necessary because some STL implementations crash when
+  //   you call string::append(NULL, 0), presumably because they are trying to
+  //   be helpful by detecting the NULL pointer, even though there's nothing
+  //   wrong with reading zero bytes from NULL.
+  if (buffer_pos_ != token_start_) {
+    current_.text.append(buffer_ + token_start_, buffer_pos_ - token_start_);
+  }
+  token_start_ = -1;
+}
+
+// -------------------------------------------------------------------
+// Helper methods that consume characters.
+
+template<typename CharacterClass>
+inline bool Tokenizer::LookingAt() {
+  return CharacterClass::InClass(current_char_);
+}
+
+template<typename CharacterClass>
+inline bool Tokenizer::TryConsumeOne() {
+  if (CharacterClass::InClass(current_char_)) {
+    NextChar();
+    return true;
+  } else {
+    return false;
+  }
+}
+
+inline bool Tokenizer::TryConsume(char c) {
+  if (current_char_ == c) {
+    NextChar();
+    return true;
+  } else {
+    return false;
+  }
+}
+
+template<typename CharacterClass>
+inline void Tokenizer::ConsumeZeroOrMore() {
+  while (CharacterClass::InClass(current_char_)) {
+    NextChar();
+  }
+}
+
+template<typename CharacterClass>
+inline void Tokenizer::ConsumeOneOrMore(const char* error) {
+  if (!CharacterClass::InClass(current_char_)) {
+    AddError(error);
+  } else {
+    do {
+      NextChar();
+    } while (CharacterClass::InClass(current_char_));
+  }
+}
+
+// -------------------------------------------------------------------
+// Methods that read whole patterns matching certain kinds of tokens
+// or comments.
+
+void Tokenizer::ConsumeString(char delimiter) {
+  while (true) {
+    switch (current_char_) {
+      case '\0':
+      case '\n': {
+        AddError("String literals cannot cross line boundaries.");
+        return;
+      }
+
+      case '\\': {
+        // An escape sequence.
+        NextChar();
+        if (TryConsumeOne<Escape>()) {
+          // Valid escape sequence.
+        } else if (TryConsumeOne<OctalDigit>()) {
+          // Possibly followed by two more octal digits, but these will
+          // just be consumed by the main loop anyway so we don't need
+          // to do so explicitly here.
+        } else if (TryConsume('x') || TryConsume('X')) {
+          if (!TryConsumeOne<HexDigit>()) {
+            AddError("Expected hex digits for escape sequence.");
+          }
+          // Possibly followed by another hex digit, but again we don't care.
+        } else {
+          AddError("Invalid escape sequence in string literal.");
+        }
+        break;
+      }
+
+      default: {
+        if (current_char_ == delimiter) {
+          NextChar();
+          return;
+        }
+        NextChar();
+        break;
+      }
+    }
+  }
+}
+
+Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero,
+                                              bool started_with_dot) {
+  bool is_float = false;
+
+  if (started_with_zero && (TryConsume('x') || TryConsume('X'))) {
+    // A hex number (started with "0x").
+    ConsumeOneOrMore<HexDigit>("\"0x\" must be followed by hex digits.");
+
+  } else if (started_with_zero && LookingAt<Digit>()) {
+    // An octal number (had a leading zero).
+    ConsumeZeroOrMore<OctalDigit>();
+    if (LookingAt<Digit>()) {
+      AddError("Numbers starting with leading zero must be in octal.");
+      ConsumeZeroOrMore<Digit>();
+    }
+
+  } else {
+    // A decimal number.
+    if (started_with_dot) {
+      is_float = true;
+      ConsumeZeroOrMore<Digit>();
+    } else {
+      ConsumeZeroOrMore<Digit>();
+
+      if (TryConsume('.')) {
+        is_float = true;
+        ConsumeZeroOrMore<Digit>();
+      }
+    }
+
+    if (TryConsume('e') || TryConsume('E')) {
+      is_float = true;
+      TryConsume('-') || TryConsume('+');
+      ConsumeOneOrMore<Digit>("\"e\" must be followed by exponent.");
+    }
+
+    if (allow_f_after_float_ && (TryConsume('f') || TryConsume('F'))) {
+      is_float = true;
+    }
+  }
+
+  if (LookingAt<Letter>()) {
+    AddError("Need space between number and identifier.");
+  } else if (current_char_ == '.') {
+    if (is_float) {
+      AddError(
+        "Already saw decimal point or exponent; can't have another one.");
+    } else {
+      AddError("Hex and octal numbers must be integers.");
+    }
+  }
+
+  return is_float ? TYPE_FLOAT : TYPE_INTEGER;
+}
+
+void Tokenizer::ConsumeLineComment() {
+  while (current_char_ != '\0' && current_char_ != '\n') {
+    NextChar();
+  }
+  TryConsume('\n');
+}
+
+void Tokenizer::ConsumeBlockComment() {
+  int start_line = line_;
+  int start_column = column_ - 2;
+
+  while (true) {
+    while (current_char_ != '\0' &&
+           current_char_ != '*' &&
+           current_char_ != '/') {
+      NextChar();
+    }
+
+    if (TryConsume('*') && TryConsume('/')) {
+      // End of comment.
+      break;
+    } else if (TryConsume('/') && current_char_ == '*') {
+      // Note:  We didn't consume the '*' because if there is a '/' after it
+      //   we want to interpret that as the end of the comment.
+      AddError(
+        "\"/*\" inside block comment.  Block comments cannot be nested.");
+    } else if (current_char_ == '\0') {
+      AddError("End-of-file inside block comment.");
+      error_collector_->AddError(
+        start_line, start_column, "  Comment started here.");
+      break;
+    }
+  }
+}
+
+// -------------------------------------------------------------------
+
+bool Tokenizer::Next() {
+  TokenType last_token_type = current_.type;
+
+  // Did we skip any characters after the last token?
+  bool skipped_stuff = false;
+
+  while (!read_error_) {
+    if (TryConsumeOne<Whitespace>()) {
+      ConsumeZeroOrMore<Whitespace>();
+
+    } else if (comment_style_ == CPP_COMMENT_STYLE && TryConsume('/')) {
+      // Starting a comment?
+      if (TryConsume('/')) {
+        ConsumeLineComment();
+      } else if (TryConsume('*')) {
+        ConsumeBlockComment();
+      } else {
+        // Oops, it was just a slash.  Return it.
+        current_.type = TYPE_SYMBOL;
+        current_.text = "/";
+        current_.line = line_;
+        current_.column = column_ - 1;
+        return true;
+      }
+
+    } else if (comment_style_ == SH_COMMENT_STYLE && TryConsume('#')) {
+      ConsumeLineComment();
+
+    } else if (LookingAt<Unprintable>() || current_char_ == '\0') {
+      AddError("Invalid control characters encountered in text.");
+      NextChar();
+      // Skip more unprintable characters, too.  But, remember that '\0' is
+      // also what current_char_ is set to after EOF / read error.  We have
+      // to be careful not to go into an infinite loop of trying to consume
+      // it, so make sure to check read_error_ explicitly before consuming
+      // '\0'.
+      while (TryConsumeOne<Unprintable>() ||
+             (!read_error_ && TryConsume('\0'))) {
+        // Ignore.
+      }
+
+    } else {
+      // Reading some sort of token.
+      StartToken();
+
+      if (TryConsumeOne<Letter>()) {
+        ConsumeZeroOrMore<Alphanumeric>();
+        current_.type = TYPE_IDENTIFIER;
+      } else if (TryConsume('0')) {
+        current_.type = ConsumeNumber(true, false);
+      } else if (TryConsume('.')) {
+        // This could be the beginning of a floating-point number, or it could
+        // just be a '.' symbol.
+
+        if (TryConsumeOne<Digit>()) {
+          // It's a floating-point number.
+          if (last_token_type == TYPE_IDENTIFIER && !skipped_stuff) {
+            // We don't accept syntax like "blah.123".
+            error_collector_->AddError(line_, column_ - 2,
+              "Need space between identifier and decimal point.");
+          }
+          current_.type = ConsumeNumber(false, true);
+        } else {
+          current_.type = TYPE_SYMBOL;
+        }
+      } else if (TryConsumeOne<Digit>()) {
+        current_.type = ConsumeNumber(false, false);
+      } else if (TryConsume('\"')) {
+        ConsumeString('\"');
+        current_.type = TYPE_STRING;
+      } else if (TryConsume('\'')) {
+        ConsumeString('\'');
+        current_.type = TYPE_STRING;
+      } else {
+        NextChar();
+        current_.type = TYPE_SYMBOL;
+      }
+
+      EndToken();
+      return true;
+    }
+
+    skipped_stuff = true;
+  }
+
+  // EOF
+  current_.type = TYPE_END;
+  current_.text.clear();
+  current_.line = line_;
+  current_.column = column_;
+  return false;
+}
+
+// -------------------------------------------------------------------
+// Token-parsing helpers.  Remember that these don't need to report
+// errors since any errors should already have been reported while
+// tokenizing.  Also, these can assume that whatever text they
+// are given is text that the tokenizer actually parsed as a token
+// of the given type.
+
+bool Tokenizer::ParseInteger(const string& text, uint64 max_value,
+                             uint64* output) {
+  // Sadly, we can't just use strtoul() since it is only 32-bit and strtoull()
+  // is non-standard.  I hate the C standard library.  :(
+
+//  return strtoull(text.c_str(), NULL, 0);
+
+  const char* ptr = text.c_str();
+  int base = 10;
+  if (ptr[0] == '0') {
+    if (ptr[1] == 'x') {
+      // This is hex.
+      base = 16;
+      ptr += 2;
+    } else {
+      // This is octal.
+      base = 8;
+    }
+  }
+
+  uint64 result = 0;
+  for (; *ptr != '\0'; ptr++) {
+    int digit = DigitValue(*ptr);
+    GOOGLE_LOG_IF(DFATAL, digit < 0 || digit >= base)
+      << " Tokenizer::ParseInteger() passed text that could not have been"
+         " tokenized as an integer: " << CEscape(text);
+    if (digit > max_value || result > (max_value - digit) / base) {
+      // Overflow.
+      return false;
+    }
+    result = result * base + digit;
+  }
+
+  *output = result;
+  return true;
+}
+
+double Tokenizer::ParseFloat(const string& text) {
+  const char* start = text.c_str();
+  char* end;
+  double result = NoLocaleStrtod(start, &end);
+
+  // "1e" is not a valid float, but if the tokenizer reads it, it will
+  // report an error but still return it as a valid token.  We need to
+  // accept anything the tokenizer could possibly return, error or not.
+  if (*end == 'e' || *end == 'E') {
+    ++end;
+    if (*end == '-' || *end == '+') ++end;
+  }
+
+  // If the Tokenizer had allow_f_after_float_ enabled, the float may be
+  // suffixed with the letter 'f'.
+  if (*end == 'f' || *end == 'F') {
+    ++end;
+  }
+
+  GOOGLE_LOG_IF(DFATAL, end - start != text.size() || *start == '-')
+    << " Tokenizer::ParseFloat() passed text that could not have been"
+       " tokenized as a float: " << CEscape(text);
+  return result;
+}
+
+void Tokenizer::ParseString(const string& text, string* output) {
+  output->clear();
+
+  // Reminder:  text[0] is always the quote character.  (If text is
+  //   empty, it's invalid, so we'll just return.)
+  if (text.empty()) {
+    GOOGLE_LOG(DFATAL)
+      << " ParseString::ParseString() passed text that could not have been"
+         " tokenized as a string: " << CEscape(text);
+    return;
+  }
+
+  output->reserve(text.size());
+
+  // Loop through the string copying characters to "output" and
+  // interpreting escape sequences.  Note that any invalid escape
+  // sequences or other errors were already reported while tokenizing.
+  // In this case we do not need to produce valid results.
+  for (const char* ptr = text.c_str() + 1; *ptr != '\0'; ptr++) {
+    if (*ptr == '\\' && ptr[1] != '\0') {
+      // An escape sequence.
+      ++ptr;
+
+      if (OctalDigit::InClass(*ptr)) {
+        // An octal escape.  May one, two, or three digits.
+        int code = DigitValue(*ptr);
+        if (OctalDigit::InClass(ptr[1])) {
+          ++ptr;
+          code = code * 8 + DigitValue(*ptr);
+        }
+        if (OctalDigit::InClass(ptr[1])) {
+          ++ptr;
+          code = code * 8 + DigitValue(*ptr);
+        }
+        output->push_back(static_cast<char>(code));
+
+      } else if (*ptr == 'x') {
+        // A hex escape.  May zero, one, or two digits.  (The zero case
+        // will have been caught as an error earlier.)
+        int code = 0;
+        if (HexDigit::InClass(ptr[1])) {
+          ++ptr;
+          code = DigitValue(*ptr);
+        }
+        if (HexDigit::InClass(ptr[1])) {
+          ++ptr;
+          code = code * 16 + DigitValue(*ptr);
+        }
+        output->push_back(static_cast<char>(code));
+
+      } else {
+        // Some other escape code.
+        output->push_back(TranslateEscape(*ptr));
+      }
+
+    } else if (*ptr == text[0]) {
+      // Ignore quote matching the starting quote.
+    } else {
+      output->push_back(*ptr);
+    }
+  }
+
+  return;
+}
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/io/tokenizer.h b/src/google/protobuf/io/tokenizer.h
new file mode 100644
index 0000000..841564c
--- /dev/null
+++ b/src/google/protobuf/io/tokenizer.h
@@ -0,0 +1,276 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Class for parsing tokenized text from a ZeroCopyInputStream.
+
+#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__
+#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+class ZeroCopyInputStream;     // zero_copy_stream.h
+
+// Defined in this file.
+class ErrorCollector;
+class Tokenizer;
+
+// Abstract interface for an object which collects the errors that occur
+// during parsing.  A typical implementation might simply print the errors
+// to stdout.
+class LIBPROTOBUF_EXPORT ErrorCollector {
+ public:
+  inline ErrorCollector() {}
+  virtual ~ErrorCollector();
+
+  // Indicates that there was an error in the input at the given line and
+  // column numbers.  The numbers are zero-based, so you may want to add
+  // 1 to each before printing them.
+  virtual void AddError(int line, int column, const string& message) = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
+};
+
+// This class converts a stream of raw text into a stream of tokens for
+// the protocol definition parser to parse.  The tokens recognized are
+// similar to those that make up the C language; see the TokenType enum for
+// precise descriptions.  Whitespace and comments are skipped.  By default,
+// C- and C++-style comments are recognized, but other styles can be used by
+// calling set_comment_style().
+class LIBPROTOBUF_EXPORT Tokenizer {
+ public:
+  // Construct a Tokenizer that reads and tokenizes text from the given
+  // input stream and writes errors to the given error_collector.
+  // The caller keeps ownership of input and error_collector.
+  Tokenizer(ZeroCopyInputStream* input, ErrorCollector* error_collector);
+  ~Tokenizer();
+
+  enum TokenType {
+    TYPE_START,       // Next() has not yet been called.
+    TYPE_END,         // End of input reached.  "text" is empty.
+
+    TYPE_IDENTIFIER,  // A sequence of letters, digits, and underscores, not
+                      // starting with a digit.  It is an error for a number
+                      // to be followed by an identifier with no space in
+                      // between.
+    TYPE_INTEGER,     // A sequence of digits representing an integer.  Normally
+                      // the digits are decimal, but a prefix of "0x" indicates
+                      // a hex number and a leading zero indicates octal, just
+                      // like with C numeric literals.  A leading negative sign
+                      // is NOT included in the token; it's up to the parser to
+                      // interpret the unary minus operator on its own.
+    TYPE_FLOAT,       // A floating point literal, with a fractional part and/or
+                      // an exponent.  Always in decimal.  Again, never
+                      // negative.
+    TYPE_STRING,      // A quoted sequence of escaped characters.  Either single
+                      // or double quotes can be used, but they must match.
+                      // A string literal cannot cross a line break.
+    TYPE_SYMBOL,      // Any other printable character, like '!' or '+'.
+                      // Symbols are always a single character, so "!+$%" is
+                      // four tokens.
+  };
+
+  // Structure representing a token read from the token stream.
+  struct Token {
+    TokenType type;
+    string text;       // The exact text of the token as it appeared in
+                       // the input.  e.g. tokens of TYPE_STRING will still
+                       // be escaped and in quotes.
+
+    // "line" and "column" specify the position of the first character of
+    // the token within the input stream.  They are zero-based.
+    int line;
+    int column;
+  };
+
+  // Get the current token.  This is updated when Next() is called.  Before
+  // the first call to Next(), current() has type TYPE_START and no contents.
+  const Token& current();
+
+  // Advance to the next token.  Returns false if the end of the input is
+  // reached.
+  bool Next();
+
+  // Parse helpers ---------------------------------------------------
+
+  // Parses a TYPE_FLOAT token.  This never fails, so long as the text actually
+  // comes from a TYPE_FLOAT token parsed by Tokenizer.  If it doesn't, the
+  // result is undefined (possibly an assert failure).
+  static double ParseFloat(const string& text);
+
+  // Parses a TYPE_STRING token.  This never fails, so long as the text actually
+  // comes from a TYPE_STRING token parsed by Tokenizer.  If it doesn't, the
+  // result is undefined (possibly an assert failure).
+  static void ParseString(const string& text, string* output);
+
+  // Parses a TYPE_INTEGER token.  Returns false if the result would be
+  // greater than max_value.  Otherwise, returns true and sets *output to the
+  // result.  If the text is not from a Token of type TYPE_INTEGER originally
+  // parsed by a Tokenizer, the result is undefined (possibly an assert
+  // failure).
+  static bool ParseInteger(const string& text, uint64 max_value,
+                           uint64* output);
+
+  // Options ---------------------------------------------------------
+
+  // Set true to allow floats to be suffixed with the letter 'f'.  Tokens
+  // which would otherwise be integers but which have the 'f' suffix will be
+  // forced to be interpreted as floats.  For all other purposes, the 'f' is
+  // ignored.
+  void set_allow_f_after_float(bool value) { allow_f_after_float_ = value; }
+
+  // Valid values for set_comment_style().
+  enum CommentStyle {
+    // Line comments begin with "//", block comments are delimited by "/*" and
+    // "*/".
+    CPP_COMMENT_STYLE,
+    // Line comments begin with "#".  No way to write block comments.
+    SH_COMMENT_STYLE
+  };
+
+  // Sets the comment style.
+  void set_comment_style(CommentStyle style) { comment_style_ = style; }
+
+  // -----------------------------------------------------------------
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer);
+
+  Token current_;           // Returned by current().
+
+  ZeroCopyInputStream* input_;
+  ErrorCollector* error_collector_;
+
+  char current_char_;       // == buffer_[buffer_pos_], updated by NextChar().
+  const char* buffer_;      // Current buffer returned from input_.
+  int buffer_size_;         // Size of buffer_.
+  int buffer_pos_;          // Current position within the buffer.
+  bool read_error_;         // Did we previously encounter a read error?
+
+  // Line and column number of current_char_ within the whole input stream.
+  int line_;
+  int column_;
+
+  // Position in buffer_ where StartToken() was called.  If the token
+  // started in the previous buffer, this is zero, and current_.text already
+  // contains the part of the token from the previous buffer.  If not
+  // currently parsing a token, this is -1.
+  int token_start_;
+
+  // Options.
+  bool allow_f_after_float_;
+  CommentStyle comment_style_;
+
+  // Since we count columns we need to interpret tabs somehow.  We'll take
+  // the standard 8-character definition for lack of any way to do better.
+  static const int kTabWidth = 8;
+
+  // -----------------------------------------------------------------
+  // Helper methods.
+
+  // Consume this character and advance to the next one.
+  void NextChar();
+
+  // Read a new buffer from the input.
+  void Refresh();
+
+  // Called when the current character is the first character of a new
+  // token (not including whitespace or comments).
+  inline void StartToken();
+  // Called when the current character is the first character after the
+  // end of the last token.  After this returns, current_.text will
+  // contain all text consumed since StartToken() was called.
+  inline void EndToken();
+
+  // Convenience method to add an error at the current line and column.
+  void AddError(const string& message) {
+    error_collector_->AddError(line_, column_, message);
+  }
+
+  // -----------------------------------------------------------------
+  // The following four methods are used to consume tokens of specific
+  // types.  They are actually used to consume all characters *after*
+  // the first, since the calling function consumes the first character
+  // in order to decide what kind of token is being read.
+
+  // Read and consume a string, ending when the given delimiter is
+  // consumed.
+  void ConsumeString(char delimiter);
+
+  // Read and consume a number, returning TYPE_FLOAT or TYPE_INTEGER
+  // depending on what was read.  This needs to know if the first
+  // character was a zero in order to correctly recognize hex and octal
+  // numbers.
+  // It also needs to know if the first characted was a . to parse floating
+  // point correctly.
+  TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot);
+
+  // Consume the rest of a line.
+  void ConsumeLineComment();
+  // Consume until "*/".
+  void ConsumeBlockComment();
+
+  // -----------------------------------------------------------------
+  // These helper methods make the parsing code more readable.  The
+  // "character classes" refered to are defined at the top of the .cc file.
+  // Basically it is a C++ class with one method:
+  //   static bool InClass(char c);
+  // The method returns true if c is a member of this "class", like "Letter"
+  // or "Digit".
+
+  // Returns true if the current character is of the given character
+  // class, but does not consume anything.
+  template<typename CharacterClass>
+  inline bool LookingAt();
+
+  // If the current character is in the given class, consume it and return
+  // true.  Otherwise return false.
+  // e.g. TryConsumeOne<Letter>()
+  template<typename CharacterClass>
+  inline bool TryConsumeOne();
+
+  // Like above, but try to consume the specific character indicated.
+  inline bool TryConsume(char c);
+
+  // Consume zero or more of the given character class.
+  template<typename CharacterClass>
+  inline void ConsumeZeroOrMore();
+
+  // Consume one or more of the given character class or log the given
+  // error message.
+  // e.g. ConsumeOneOrMore<Digit>("Expected digits.");
+  template<typename CharacterClass>
+  inline void ConsumeOneOrMore(const char* error);
+};
+
+// inline methods ====================================================
+inline const Tokenizer::Token& Tokenizer::current() {
+  return current_;
+}
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_TOKENIZER_H__
diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc
new file mode 100644
index 0000000..e2cede7
--- /dev/null
+++ b/src/google/protobuf/io/tokenizer_unittest.cc
@@ -0,0 +1,706 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <vector>
+#include <math.h>
+#include <limits.h>
+
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+// ===================================================================
+// Data-Driven Test Infrastructure
+
+// TODO(kenton):  This is copied from coded_stream_unittest.  This is
+//   temporary until these fetaures are integrated into gTest itself.
+
+// TEST_1D and TEST_2D are macros I'd eventually like to see added to
+// gTest.  These macros can be used to declare tests which should be
+// run multiple times, once for each item in some input array.  TEST_1D
+// tests all cases in a single input array.  TEST_2D tests all
+// combinations of cases from two arrays.  The arrays must be statically
+// defined such that the GOOGLE_ARRAYSIZE() macro works on them.  Example:
+//
+// int kCases[] = {1, 2, 3, 4}
+// TEST_1D(MyFixture, MyTest, kCases) {
+//   EXPECT_GT(kCases_case, 0);
+// }
+//
+// This test iterates through the numbers 1, 2, 3, and 4 and tests that
+// they are all grater than zero.  In case of failure, the exact case
+// which failed will be printed.  The case type must be printable using
+// ostream::operator<<.
+
+#define TEST_1D(FIXTURE, NAME, CASES)                                      \
+  class FIXTURE##_##NAME##_DD : public FIXTURE {                           \
+   protected:                                                              \
+    template <typename CaseType>                                           \
+    void DoSingleCase(const CaseType& CASES##_case);                       \
+  };                                                                       \
+                                                                           \
+  TEST_F(FIXTURE##_##NAME##_DD, NAME) {                                    \
+    for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) {                           \
+      SCOPED_TRACE(testing::Message()                                      \
+        << #CASES " case #" << i << ": " << CASES[i]);                     \
+      DoSingleCase(CASES[i]);                                              \
+    }                                                                      \
+  }                                                                        \
+                                                                           \
+  template <typename CaseType>                                             \
+  void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
+
+#define TEST_2D(FIXTURE, NAME, CASES1, CASES2)                             \
+  class FIXTURE##_##NAME##_DD : public FIXTURE {                           \
+   protected:                                                              \
+    template <typename CaseType1, typename CaseType2>                      \
+    void DoSingleCase(const CaseType1& CASES1##_case,                      \
+                      const CaseType2& CASES2##_case);                     \
+  };                                                                       \
+                                                                           \
+  TEST_F(FIXTURE##_##NAME##_DD, NAME) {                                    \
+    for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) {                          \
+      for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) {                        \
+        SCOPED_TRACE(testing::Message()                                    \
+          << #CASES1 " case #" << i << ": " << CASES1[i] << ", "           \
+          << #CASES2 " case #" << j << ": " << CASES2[j]);                 \
+        DoSingleCase(CASES1[i], CASES2[j]);                                \
+      }                                                                    \
+    }                                                                      \
+  }                                                                        \
+                                                                           \
+  template <typename CaseType1, typename CaseType2>                        \
+  void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
+                                           const CaseType2& CASES2##_case)
+
+// -------------------------------------------------------------------
+
+// An input stream that is basically like an ArrayInputStream but sometimes
+// returns empty buffers, just to throw us off.
+class TestInputStream : public ZeroCopyInputStream {
+ public:
+  TestInputStream(const void* data, int size, int block_size)
+    : array_stream_(data, size, block_size), counter_(0) {}
+  ~TestInputStream() {}
+
+  // implements ZeroCopyInputStream ----------------------------------
+  bool Next(const void** data, int* size) {
+    // We'll return empty buffers starting with the first buffer, and every
+    // 3 and 5 buffers after that.
+    if (counter_ % 3 == 0 || counter_ % 5 == 0) {
+      *data = NULL;
+      *size = 0;
+      ++counter_;
+      return true;
+    } else {
+      ++counter_;
+      return array_stream_.Next(data, size);
+    }
+  }
+
+  void BackUp(int count)  { return array_stream_.BackUp(count); }
+  bool Skip(int count)    { return array_stream_.Skip(count);   }
+  int64 ByteCount() const { return array_stream_.ByteCount();   }
+
+ private:
+  ArrayInputStream array_stream_;
+  int counter_;
+};
+
+// -------------------------------------------------------------------
+
+// An error collector which simply concatenates all its errors into a big
+// block of text which can be checked.
+class TestErrorCollector : public ErrorCollector {
+ public:
+  TestErrorCollector() {}
+  ~TestErrorCollector() {}
+
+  string text_;
+
+  // implements ErrorCollector ---------------------------------------
+  void AddError(int line, int column, const string& message) {
+    strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
+                                 line, column, message);
+  }
+};
+
+// -------------------------------------------------------------------
+
+// We test each operation over a variety of block sizes to insure that
+// we test cases where reads cross buffer boundaries as well as cases
+// where they don't.  This is sort of a brute-force approach to this,
+// but it's easy to write and easy to understand.
+const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
+
+class TokenizerTest : public testing::Test {
+ protected:
+  // For easy testing.
+  uint64 ParseInteger(const string& text) {
+    uint64 result;
+    EXPECT_TRUE(Tokenizer::ParseInteger(text, kuint64max, &result));
+    return result;
+  }
+};
+
+// ===================================================================
+
+// These tests causes gcc 3.3.5 (and earlier?) to give the cryptic error:
+//   "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
+#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
+
+// In each test case, the entire input text should parse as a single token
+// of the given type.
+struct SimpleTokenCase {
+  string input;
+  Tokenizer::TokenType type;
+};
+
+inline ostream& operator<<(ostream& out,
+                           const SimpleTokenCase& test_case) {
+  return out << CEscape(test_case.input);
+}
+
+SimpleTokenCase kSimpleTokenCases[] = {
+  // Test identifiers.
+  { "hello",       Tokenizer::TYPE_IDENTIFIER },
+
+  // Test integers.
+  { "123",         Tokenizer::TYPE_INTEGER },
+  { "0xab6",       Tokenizer::TYPE_INTEGER },
+  { "0XAB6",       Tokenizer::TYPE_INTEGER },
+  { "0X1234567",   Tokenizer::TYPE_INTEGER },
+  { "0x89abcdef",  Tokenizer::TYPE_INTEGER },
+  { "0x89ABCDEF",  Tokenizer::TYPE_INTEGER },
+  { "01234567",    Tokenizer::TYPE_INTEGER },
+
+  // Test floats.
+  { "123.45",      Tokenizer::TYPE_FLOAT },
+  { "1.",          Tokenizer::TYPE_FLOAT },
+  { "1e3",         Tokenizer::TYPE_FLOAT },
+  { "1E3",         Tokenizer::TYPE_FLOAT },
+  { "1e-3",        Tokenizer::TYPE_FLOAT },
+  { "1e+3",        Tokenizer::TYPE_FLOAT },
+  { "1.e3",        Tokenizer::TYPE_FLOAT },
+  { "1.2e3",       Tokenizer::TYPE_FLOAT },
+  { ".1",          Tokenizer::TYPE_FLOAT },
+  { ".1e3",        Tokenizer::TYPE_FLOAT },
+  { ".1e-3",       Tokenizer::TYPE_FLOAT },
+  { ".1e+3",       Tokenizer::TYPE_FLOAT },
+
+  // Test strings.
+  { "'hello'",     Tokenizer::TYPE_STRING },
+  { "\"foo\"",     Tokenizer::TYPE_STRING },
+  { "'a\"b'",      Tokenizer::TYPE_STRING },
+  { "\"a'b\"",     Tokenizer::TYPE_STRING },
+  { "'a\\'b'",     Tokenizer::TYPE_STRING },
+  { "\"a\\\"b\"",  Tokenizer::TYPE_STRING },
+  { "'\\xf'",      Tokenizer::TYPE_STRING },
+  { "'\\0'",       Tokenizer::TYPE_STRING },
+
+  // Test symbols.
+  { "+",           Tokenizer::TYPE_SYMBOL },
+  { ".",           Tokenizer::TYPE_SYMBOL },
+};
+
+TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) {
+  // Set up the tokenizer.
+  TestInputStream input(kSimpleTokenCases_case.input.data(),
+                        kSimpleTokenCases_case.input.size(),
+                        kBlockSizes_case);
+  TestErrorCollector error_collector;
+  Tokenizer tokenizer(&input, &error_collector);
+
+  // Before Next() is called, the initial token should always be TYPE_START.
+  EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type);
+  EXPECT_EQ("", tokenizer.current().text);
+  EXPECT_EQ(0, tokenizer.current().line);
+  EXPECT_EQ(0, tokenizer.current().column);
+
+  // Parse the token.
+  ASSERT_TRUE(tokenizer.Next());
+
+  // Check that it has the right type.
+  EXPECT_EQ(kSimpleTokenCases_case.type, tokenizer.current().type);
+  // Check that it contains the complete input text.
+  EXPECT_EQ(kSimpleTokenCases_case.input, tokenizer.current().text);
+  // Check that it is located at the beginning of the input
+  EXPECT_EQ(0, tokenizer.current().line);
+  EXPECT_EQ(0, tokenizer.current().column);
+
+  // There should be no more input.
+  EXPECT_FALSE(tokenizer.Next());
+
+  // After Next() returns false, the token should have type TYPE_END.
+  EXPECT_EQ(Tokenizer::TYPE_END, tokenizer.current().type);
+  EXPECT_EQ("", tokenizer.current().text);
+  EXPECT_EQ(0, tokenizer.current().line);
+  EXPECT_EQ(kSimpleTokenCases_case.input.size(), tokenizer.current().column);
+
+  // There should be no errors.
+  EXPECT_TRUE(error_collector.text_.empty());
+}
+
+TEST_1D(TokenizerTest, FloatSuffix, kBlockSizes) {
+  // Test the "allow_f_after_float" option.
+
+  // Set up the tokenizer.
+  const char* text = "1f 2.5f 6e3f 7F";
+  TestInputStream input(text, strlen(text), kBlockSizes_case);
+  TestErrorCollector error_collector;
+  Tokenizer tokenizer(&input, &error_collector);
+  tokenizer.set_allow_f_after_float(true);
+
+  // Advance through tokens and check that they are parsed as expected.
+  ASSERT_TRUE(tokenizer.Next());
+  EXPECT_EQ(tokenizer.current().text, "1f");
+  EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+  ASSERT_TRUE(tokenizer.Next());
+  EXPECT_EQ(tokenizer.current().text, "2.5f");
+  EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+  ASSERT_TRUE(tokenizer.Next());
+  EXPECT_EQ(tokenizer.current().text, "6e3f");
+  EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+  ASSERT_TRUE(tokenizer.Next());
+  EXPECT_EQ(tokenizer.current().text, "7F");
+  EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+
+  // There should be no more input.
+  EXPECT_FALSE(tokenizer.Next());
+  // There should be no errors.
+  EXPECT_TRUE(error_collector.text_.empty());
+}
+
+#endif
+
+// -------------------------------------------------------------------
+
+// In each case, the input is parsed to produce a list of tokens.  The
+// last token in "output" must have type TYPE_END.
+struct MultiTokenCase {
+  string input;
+  Tokenizer::Token output[10];  // The compiler wants a constant array
+                                // size for initialization to work.  There
+                                // is no reason this can't be increased if
+                                // needed.
+};
+
+inline ostream& operator<<(ostream& out,
+                           const MultiTokenCase& test_case) {
+  return out << CEscape(test_case.input);
+}
+
+MultiTokenCase kMultiTokenCases[] = {
+  // Test empty input.
+  { "", {
+    { Tokenizer::TYPE_END       , ""     , 0,  0 },
+  }},
+
+  // Test all token types at the same time.
+  { "foo 1 1.2 + 'bar'", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo"  , 0,  0 },
+    { Tokenizer::TYPE_INTEGER   , "1"    , 0,  4 },
+    { Tokenizer::TYPE_FLOAT     , "1.2"  , 0,  6 },
+    { Tokenizer::TYPE_SYMBOL    , "+"    , 0, 10 },
+    { Tokenizer::TYPE_STRING    , "'bar'", 0, 12 },
+    { Tokenizer::TYPE_END       , ""     , 0, 17 },
+  }},
+
+  // Test that consecutive symbols are parsed as separate tokens.
+  { "!@+%", {
+    { Tokenizer::TYPE_SYMBOL    , "!"    , 0, 0 },
+    { Tokenizer::TYPE_SYMBOL    , "@"    , 0, 1 },
+    { Tokenizer::TYPE_SYMBOL    , "+"    , 0, 2 },
+    { Tokenizer::TYPE_SYMBOL    , "%"    , 0, 3 },
+    { Tokenizer::TYPE_END       , ""     , 0, 4 },
+  }},
+
+  // Test that newlines affect line numbers correctly.
+  { "foo bar\nrab oof", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0,  0 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 0,  4 },
+    { Tokenizer::TYPE_IDENTIFIER, "rab", 1,  0 },
+    { Tokenizer::TYPE_IDENTIFIER, "oof", 1,  4 },
+    { Tokenizer::TYPE_END       , ""   , 1,  7 },
+  }},
+
+  // Test that tabs affect column numbers correctly.
+  { "foo\tbar  \tbaz", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0,  0 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 0,  8 },
+    { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16 },
+    { Tokenizer::TYPE_END       , ""   , 0, 19 },
+  }},
+
+  // Test that line comments are ignored.
+  { "foo // This is a comment\n"
+    "bar // This is another comment", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0,  0 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 1,  0 },
+    { Tokenizer::TYPE_END       , ""   , 1, 30 },
+  }},
+
+  // Test that block comments are ignored.
+  { "foo /* This is a block comment */ bar", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0,  0 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34 },
+    { Tokenizer::TYPE_END       , ""   , 0, 37 },
+  }},
+
+  // Test that sh-style comments are not ignored by default.
+  { "foo # bar\n"
+    "baz", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0,  0 },
+    { Tokenizer::TYPE_SYMBOL    , "#"  , 0,  4 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 0,  6 },
+    { Tokenizer::TYPE_IDENTIFIER, "baz", 1,  0 },
+    { Tokenizer::TYPE_END       , ""   , 1, 3 },
+  }},
+};
+
+TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) {
+  // Set up the tokenizer.
+  TestInputStream input(kMultiTokenCases_case.input.data(),
+                        kMultiTokenCases_case.input.size(),
+                        kBlockSizes_case);
+  TestErrorCollector error_collector;
+  Tokenizer tokenizer(&input, &error_collector);
+
+  // Before Next() is called, the initial token should always be TYPE_START.
+  EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type);
+  EXPECT_EQ("", tokenizer.current().text);
+  EXPECT_EQ(0, tokenizer.current().line);
+  EXPECT_EQ(0, tokenizer.current().column);
+
+  // Loop through all expected tokens.
+  int i = 0;
+  Tokenizer::Token token;
+  do {
+    token = kMultiTokenCases_case.output[i++];
+
+    SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text);
+
+    // Next() should only return false when it hits the end token.
+    if (token.type != Tokenizer::TYPE_END) {
+      ASSERT_TRUE(tokenizer.Next());
+    } else {
+      ASSERT_FALSE(tokenizer.Next());
+    }
+
+    // Check that the token matches the expected one.
+    EXPECT_EQ(token.type, tokenizer.current().type);
+    EXPECT_EQ(token.text, tokenizer.current().text);
+    EXPECT_EQ(token.line, tokenizer.current().line);
+    EXPECT_EQ(token.column, tokenizer.current().column);
+
+  } while (token.type != Tokenizer::TYPE_END);
+
+  // There should be no errors.
+  EXPECT_TRUE(error_collector.text_.empty());
+}
+
+// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error:
+//   "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
+#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
+
+TEST_1D(TokenizerTest, ShCommentStyle, kBlockSizes) {
+  // Test the "comment_style" option.
+
+  const char* text = "foo # bar\n"
+                     "baz // qux\n"
+                     "corge /* grault */\n"
+                     "garply";
+  const char* const kTokens[] = {"foo",  // "# bar" is ignored
+                                 "baz", "/", "/", "qux",
+                                 "corge", "/", "*", "grault", "*", "/",
+                                 "garply"};
+
+  // Set up the tokenizer.
+  TestInputStream input(text, strlen(text), kBlockSizes_case);
+  TestErrorCollector error_collector;
+  Tokenizer tokenizer(&input, &error_collector);
+  tokenizer.set_comment_style(Tokenizer::SH_COMMENT_STYLE);
+
+  // Advance through tokens and check that they are parsed as expected.
+  for (int i = 0; i < GOOGLE_ARRAYSIZE(kTokens); i++) {
+    EXPECT_TRUE(tokenizer.Next());
+    EXPECT_EQ(tokenizer.current().text, kTokens[i]);
+  }
+
+  // There should be no more input.
+  EXPECT_FALSE(tokenizer.Next());
+  // There should be no errors.
+  EXPECT_TRUE(error_collector.text_.empty());
+}
+
+#endif
+
+// -------------------------------------------------------------------
+
+// Test parse helpers.  It's not really worth setting up a full data-driven
+// test here.
+TEST_F(TokenizerTest, ParseInteger) {
+  EXPECT_EQ(0, ParseInteger("0"));
+  EXPECT_EQ(123, ParseInteger("123"));
+  EXPECT_EQ(0xabcdef12u, ParseInteger("0xabcdef12"));
+  EXPECT_EQ(0xabcdef12u, ParseInteger("0xABCDEF12"));
+  EXPECT_EQ(kuint64max, ParseInteger("0xFFFFFFFFFFFFFFFF"));
+  EXPECT_EQ(01234567, ParseInteger("01234567"));
+
+  // Test invalid integers that may still be tokenized as integers.
+  EXPECT_EQ(0, ParseInteger("0x"));
+
+#ifdef GTEST_HAS_DEATH_TEST  // death tests do not work on Windows yet
+  // Test invalid integers that will never be tokenized as integers.
+  EXPECT_DEBUG_DEATH(ParseInteger("zxy"),
+    "passed text that could not have been tokenized as an integer");
+  EXPECT_DEBUG_DEATH(ParseInteger("1.2"),
+    "passed text that could not have been tokenized as an integer");
+  EXPECT_DEBUG_DEATH(ParseInteger("08"),
+    "passed text that could not have been tokenized as an integer");
+  EXPECT_DEBUG_DEATH(ParseInteger("0xg"),
+    "passed text that could not have been tokenized as an integer");
+  EXPECT_DEBUG_DEATH(ParseInteger("-1"),
+    "passed text that could not have been tokenized as an integer");
+#endif  // GTEST_HAS_DEATH_TEST
+
+  // Test overflows.
+  uint64 i;
+  EXPECT_TRUE (Tokenizer::ParseInteger("0", 0, &i));
+  EXPECT_FALSE(Tokenizer::ParseInteger("1", 0, &i));
+  EXPECT_TRUE (Tokenizer::ParseInteger("1", 1, &i));
+  EXPECT_TRUE (Tokenizer::ParseInteger("12345", 12345, &i));
+  EXPECT_FALSE(Tokenizer::ParseInteger("12346", 12345, &i));
+  EXPECT_TRUE (Tokenizer::ParseInteger("0xFFFFFFFFFFFFFFFF" , kuint64max, &i));
+  EXPECT_FALSE(Tokenizer::ParseInteger("0x10000000000000000", kuint64max, &i));
+}
+
+TEST_F(TokenizerTest, ParseFloat) {
+  EXPECT_DOUBLE_EQ(1    , Tokenizer::ParseFloat("1."));
+  EXPECT_DOUBLE_EQ(1e3  , Tokenizer::ParseFloat("1e3"));
+  EXPECT_DOUBLE_EQ(1e3  , Tokenizer::ParseFloat("1E3"));
+  EXPECT_DOUBLE_EQ(1.5e3, Tokenizer::ParseFloat("1.5e3"));
+  EXPECT_DOUBLE_EQ(.1   , Tokenizer::ParseFloat(".1"));
+  EXPECT_DOUBLE_EQ(.25  , Tokenizer::ParseFloat(".25"));
+  EXPECT_DOUBLE_EQ(.1e3 , Tokenizer::ParseFloat(".1e3"));
+  EXPECT_DOUBLE_EQ(.25e3, Tokenizer::ParseFloat(".25e3"));
+  EXPECT_DOUBLE_EQ(.1e+3, Tokenizer::ParseFloat(".1e+3"));
+  EXPECT_DOUBLE_EQ(.1e-3, Tokenizer::ParseFloat(".1e-3"));
+  EXPECT_DOUBLE_EQ(5    , Tokenizer::ParseFloat("5"));
+  EXPECT_DOUBLE_EQ(6e-12, Tokenizer::ParseFloat("6e-12"));
+  EXPECT_DOUBLE_EQ(1.2  , Tokenizer::ParseFloat("1.2"));
+  EXPECT_DOUBLE_EQ(1.e2 , Tokenizer::ParseFloat("1.e2"));
+
+  // Test invalid integers that may still be tokenized as integers.
+  EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e"));
+  EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e-"));
+  EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.e"));
+
+  // Test 'f' suffix.
+  EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1f"));
+  EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.0f"));
+  EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1F"));
+
+  // These should parse successfully even though they are out of range.
+  // Overflows become infinity and underflows become zero.
+  EXPECT_EQ(     0.0, Tokenizer::ParseFloat("1e-9999999999999999999999999999"));
+  EXPECT_EQ(HUGE_VAL, Tokenizer::ParseFloat("1e+9999999999999999999999999999"));
+
+#ifdef GTEST_HAS_DEATH_TEST  // death tests do not work on Windows yet
+  // Test invalid integers that will never be tokenized as integers.
+  EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("zxy"),
+    "passed text that could not have been tokenized as a float");
+  EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("1-e0"),
+    "passed text that could not have been tokenized as a float");
+  EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("-1.0"),
+    "passed text that could not have been tokenized as a float");
+#endif  // GTEST_HAS_DEATH_TEST
+}
+
+TEST_F(TokenizerTest, ParseString) {
+  string output;
+  Tokenizer::ParseString("'hello'", &output);
+  EXPECT_EQ("hello", output);
+  Tokenizer::ParseString("\"blah\\nblah2\"", &output);
+  EXPECT_EQ("blah\nblah2", output);
+  Tokenizer::ParseString("'\\1x\\1\\123\\739\\52\\334n\\3'", &output);
+  EXPECT_EQ("\1x\1\123\739\52\334n\3", output);
+  Tokenizer::ParseString("'\\x20\\x4'", &output);
+  EXPECT_EQ("\x20\x4", output);
+
+  // Test invalid strings that may still be tokenized as strings.
+  Tokenizer::ParseString("\"\\a\\l\\v\\t", &output);  // \l is invalid
+  EXPECT_EQ("\a?\v\t", output);
+  Tokenizer::ParseString("'", &output);
+  EXPECT_EQ("", output);
+  Tokenizer::ParseString("'\\", &output);
+  EXPECT_EQ("\\", output);
+
+  // Test invalid strings that will never be tokenized as strings.
+#ifdef GTEST_HAS_DEATH_TEST  // death tests do not work on Windows yet
+  EXPECT_DEBUG_DEATH(Tokenizer::ParseString("", &output),
+    "passed text that could not have been tokenized as a string");
+#endif  // GTEST_HAS_DEATH_TEST
+}
+
+// -------------------------------------------------------------------
+
+// Each case parses some input text, ignoring the tokens produced, and
+// checks that the error output matches what is expected.
+struct ErrorCase {
+  string input;
+  bool recoverable;  // True if the tokenizer should be able to recover and
+                     // parse more tokens after seeing this error.  Cases
+                     // for which this is true must end with "foo" as
+                     // the last token, which the test will check for.
+  const char* errors;
+};
+
+inline ostream& operator<<(ostream& out,
+                           const ErrorCase& test_case) {
+  return out << CEscape(test_case.input);
+}
+
+ErrorCase kErrorCases[] = {
+  // String errors.
+  { "'\\l' foo", true,
+    "0:2: Invalid escape sequence in string literal.\n" },
+  { "'\\x' foo", true,
+    "0:3: Expected hex digits for escape sequence.\n" },
+  { "'foo", false,
+    "0:4: String literals cannot cross line boundaries.\n" },
+  { "'bar\nfoo", true,
+    "0:4: String literals cannot cross line boundaries.\n" },
+
+  // Integer errors.
+  { "123foo", true,
+    "0:3: Need space between number and identifier.\n" },
+
+  // Hex/octal errors.
+  { "0x foo", true,
+    "0:2: \"0x\" must be followed by hex digits.\n" },
+  { "0541823 foo", true,
+    "0:4: Numbers starting with leading zero must be in octal.\n" },
+  { "0x123z foo", true,
+    "0:5: Need space between number and identifier.\n" },
+  { "0x123.4 foo", true,
+    "0:5: Hex and octal numbers must be integers.\n" },
+  { "0123.4 foo", true,
+    "0:4: Hex and octal numbers must be integers.\n" },
+
+  // Float errors.
+  { "1e foo", true,
+    "0:2: \"e\" must be followed by exponent.\n" },
+  { "1e- foo", true,
+    "0:3: \"e\" must be followed by exponent.\n" },
+  { "1.2.3 foo", true,
+    "0:3: Already saw decimal point or exponent; can't have another one.\n" },
+  { "1e2.3 foo", true,
+    "0:3: Already saw decimal point or exponent; can't have another one.\n" },
+  { "a.1 foo", true,
+    "0:1: Need space between identifier and decimal point.\n" },
+  // allow_f_after_float not enabled, so this should be an error.
+  { "1.0f foo", true,
+    "0:3: Need space between number and identifier.\n" },
+
+  // Block comment errors.
+  { "/*", false,
+    "0:2: End-of-file inside block comment.\n"
+    "0:0:   Comment started here.\n"},
+  { "/*/*/ foo", true,
+    "0:3: \"/*\" inside block comment.  Block comments cannot be nested.\n"},
+
+  // Control characters.  Multiple consecutive control characters should only
+  // produce one error.
+  { "\b foo", true,
+    "0:0: Invalid control characters encountered in text.\n" },
+  { "\b\b foo", true,
+    "0:0: Invalid control characters encountered in text.\n" },
+
+  // Check that control characters at end of input don't result in an
+  // infinite loop.
+  { "\b", false,
+    "0:0: Invalid control characters encountered in text.\n" },
+
+  // Check recovery from '\0'.  We have to explicitly specify the length of
+  // these strings because otherwise the string constructor will just call
+  // strlen() which will see the first '\0' and think that is the end of the
+  // string.
+  { string("\0foo", 4), true,
+    "0:0: Invalid control characters encountered in text.\n" },
+  { string("\0\0foo", 5), true,
+    "0:0: Invalid control characters encountered in text.\n" },
+};
+
+TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) {
+  // Set up the tokenizer.
+  TestInputStream input(kErrorCases_case.input.data(),
+                        kErrorCases_case.input.size(),
+                        kBlockSizes_case);
+  TestErrorCollector error_collector;
+  Tokenizer tokenizer(&input, &error_collector);
+
+  // Ignore all input, except remember if the last token was "foo".
+  bool last_was_foo = false;
+  while (tokenizer.Next()) {
+    last_was_foo = tokenizer.current().text == "foo";
+  }
+
+  // Check that the errors match what was expected.
+  EXPECT_EQ(error_collector.text_, kErrorCases_case.errors);
+
+  // If the error was recoverable, make sure we saw "foo" after it.
+  if (kErrorCases_case.recoverable) {
+    EXPECT_TRUE(last_was_foo);
+  }
+}
+
+// -------------------------------------------------------------------
+
+TEST_1D(TokenizerTest, BackUpOnDestruction, kBlockSizes) {
+  string text = "foo bar";
+  TestInputStream input(text.data(), text.size(), kBlockSizes_case);
+
+  // Create a tokenizer, read one token, then destroy it.
+  {
+    TestErrorCollector error_collector;
+    Tokenizer tokenizer(&input, &error_collector);
+
+    tokenizer.Next();
+  }
+
+  // Only "foo" should have been read.
+  EXPECT_EQ(strlen("foo"), input.ByteCount());
+}
+
+}  // namespace
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/io/zero_copy_stream.cc b/src/google/protobuf/io/zero_copy_stream.cc
new file mode 100644
index 0000000..80559c4
--- /dev/null
+++ b/src/google/protobuf/io/zero_copy_stream.cc
@@ -0,0 +1,34 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/io/zero_copy_stream.h>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+ZeroCopyInputStream::~ZeroCopyInputStream() {}
+ZeroCopyOutputStream::~ZeroCopyOutputStream() {}
+
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/io/zero_copy_stream.h b/src/google/protobuf/io/zero_copy_stream.h
new file mode 100644
index 0000000..bce5f2d
--- /dev/null
+++ b/src/google/protobuf/io/zero_copy_stream.h
@@ -0,0 +1,224 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream
+// interfaces, which represent abstract I/O streams to and from which
+// protocol buffers can be read and written.  For a few simple
+// implementations of these interfaces, see zero_copy_stream_impl.h.
+//
+// These interfaces are different from classic I/O streams in that they
+// try to minimize the amount of data copying that needs to be done.
+// To accomplish this, responsibility for allocating buffers is moved to
+// the stream object, rather than being the responsibility of the caller.
+// So, the stream can return a buffer which actually points directly into
+// the final data structure where the bytes are to be stored, and the caller
+// can interact directly with that buffer, eliminating an intermediate copy
+// operation.
+//
+// As an example, consider the common case in which you are reading bytes
+// from an array that is already in memory (or perhaps an mmap()ed file).
+// With classic I/O streams, you would do something like:
+//   char buffer[BUFFER_SIZE];
+//   input->Read(buffer, BUFFER_SIZE);
+//   DoSomething(buffer, BUFFER_SIZE);
+// Then, the stream basically just calls memcpy() to copy the data from
+// the array into your buffer.  With a ZeroCopyInputStream, you would do
+// this instead:
+//   const void* buffer;
+//   int size;
+//   input->Next(&buffer, &size);
+//   DoSomething(buffer, size);
+// Here, no copy is performed.  The input stream returns a pointer directly
+// into the backing array, and the caller ends up reading directly from it.
+//
+// If you want to be able to read the old-fashion way, you can create
+// a CodedInputStream or CodedOutputStream wrapping these objects and use
+// their ReadRaw()/WriteRaw() methods.  These will, of course, add a copy
+// step, but Coded*Stream will handle buffering so at least it will be
+// reasonably efficient.
+//
+// ZeroCopyInputStream example:
+//   // Read in a file and print its contents to stdout.
+//   int fd = open("myfile", O_RDONLY);
+//   ZeroCopyInputStream* input = new FileInputStream(fd);
+//
+//   const void* buffer;
+//   int size;
+//   while (input->Next(&buffer, &size)) {
+//     cout.write(buffer, size);
+//   }
+//
+//   delete input;
+//   close(fd);
+//
+// ZeroCopyOutputStream example:
+//   // Copy the contents of "infile" to "outfile", using plain read() for
+//   // "infile" but a ZeroCopyOutputStream for "outfile".
+//   int infd = open("infile", O_RDONLY);
+//   int outfd = open("outfile", O_WRONLY);
+//   ZeroCopyInputStream* output = new FileOutputStream(outfd);
+//
+//   void* buffer;
+//   int size;
+//   while (output->Next(&buffer, &size)) {
+//     int bytes = read(infd, buffer, size);
+//     if (bytes < size) {
+//       // Reached EOF.
+//       output->BackUp(size - bytes);
+//       break;
+//     }
+//   }
+//
+//   delete output;
+//   close(infd);
+//   close(outfd);
+
+#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
+#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+
+namespace protobuf {
+namespace io {
+
+// Defined in this file.
+class ZeroCopyInputStream;
+class ZeroCopyOutputStream;
+
+// Abstract interface similar to an input stream but designed to minimize
+// copying.
+class LIBPROTOBUF_EXPORT ZeroCopyInputStream {
+ public:
+  inline ZeroCopyInputStream() {}
+  virtual ~ZeroCopyInputStream();
+
+  // Obtains a chunk of data from the stream.
+  //
+  // Preconditions:
+  // * "size" and "data" are not NULL.
+  //
+  // Postconditions:
+  // * If the returned value is false, there is no more data to return or
+  //   an error occurred.  All errors are permanent.
+  // * Otherwise, "size" points to the actual number of bytes read and "data"
+  //   points to a pointer to a buffer containing these bytes.
+  // * Ownership of this buffer remains with the stream, and the buffer
+  //   remains valid only until some other method of the stream is called
+  //   or the stream is destroyed.
+  // * It is legal for the returned buffer to have zero size, as long
+  //   as repeatedly calling Next() eventually yields a buffer with non-zero
+  //   size.
+  virtual bool Next(const void** data, int* size) = 0;
+
+  // Backs up a number of bytes, so that the next call to Next() returns
+  // data again that was already returned by the last call to Next().  This
+  // is useful when writing procedures that are only supposed to read up
+  // to a certain point in the input, then return.  If Next() returns a
+  // buffer that goes beyond what you wanted to read, you can use BackUp()
+  // to return to the point where you intended to finish.
+  //
+  // Preconditions:
+  // * The last method called must have been Next().
+  // * count must be less than or equal to the size of the last buffer
+  //   returned by Next().
+  //
+  // Postconditions:
+  // * The last "count" bytes of the last buffer returned by Next() will be
+  //   pushed back into the stream.  Subsequent calls to Next() will return
+  //   the same data again before producing new data.
+  virtual void BackUp(int count) = 0;
+
+  // Skips a number of bytes.  Returns false if the end of the stream is
+  // reached or some input error occurred.  In the end-of-stream case, the
+  // stream is advanced to the end of the stream (so ByteCount() will return
+  // the total size of the stream).
+  virtual bool Skip(int count) = 0;
+
+  // Returns the total number of bytes read since this object was created.
+  virtual int64 ByteCount() const = 0;
+
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream);
+};
+
+// Abstract interface similar to an output stream but designed to minimize
+// copying.
+class LIBPROTOBUF_EXPORT ZeroCopyOutputStream {
+ public:
+  inline ZeroCopyOutputStream() {}
+  virtual ~ZeroCopyOutputStream();
+
+  // Obtains a buffer into which data can be written.  Any data written
+  // into this buffer will eventually (maybe instantly, maybe later on)
+  // be written to the output.
+  //
+  // Preconditions:
+  // * "size" and "data" are not NULL.
+  //
+  // Postconditions:
+  // * If the returned value is false, an error occurred.  All errors are
+  //   permanent.
+  // * Otherwise, "size" points to the actual number of bytes in the buffer
+  //   and "data" points to the buffer.
+  // * Ownership of this buffer remains with the stream, and the buffer
+  //   remains valid only until some other method of the stream is called
+  //   or the stream is destroyed.
+  // * Any data which the caller stores in this buffer will eventually be
+  //   written to the output (unless BackUp() is called).
+  // * It is legal for the returned buffer to have zero size, as long
+  //   as repeatedly calling Next() eventually yields a buffer with non-zero
+  //   size.
+  virtual bool Next(void** data, int* size) = 0;
+
+  // Backs up a number of bytes, so that the end of the last buffer returned
+  // by Next() is not actually written.  This is needed when you finish
+  // writing all the data you want to write, but the last buffer was bigger
+  // than you needed.  You don't want to write a bunch of garbage after the
+  // end of your data, so you use BackUp() to back up.
+  //
+  // Preconditions:
+  // * The last method called must have been Next().
+  // * count must be less than or equal to the size of the last buffer
+  //   returned by Next().
+  // * The caller must not have written anything to the last "count" bytes
+  //   of that buffer.
+  //
+  // Postconditions:
+  // * The last "count" bytes of the last buffer returned by Next() will be
+  //   ignored.
+  virtual void BackUp(int count) = 0;
+
+  // Returns the total number of bytes written since this object was created.
+  virtual int64 ByteCount() const = 0;
+
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
+};
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc
new file mode 100644
index 0000000..7ff8446
--- /dev/null
+++ b/src/google/protobuf/io/zero_copy_stream_impl.cc
@@ -0,0 +1,793 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+#include <errno.h>
+#include <iostream>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+#ifdef _WIN32
+// Win32 lseek is broken:  If invoked on a non-seekable file descriptor, its
+// return value is undefined.  We re-define it to always produce an error.
+#define lseek(fd, offset, origin) ((off_t)-1)
+#endif
+
+namespace {
+
+
+// EINTR sucks.
+int close_no_eintr(int fd) {
+  int result;
+  do {
+    result = close(fd);
+  } while (result < 0 && errno == EINTR);
+  return result;
+}
+
+// Default block size for Copying{In,Out}putStreamAdaptor.
+static const int kDefaultBlockSize = 8192;
+
+}  // namespace
+
+// ===================================================================
+
+ArrayInputStream::ArrayInputStream(const void* data, int size,
+                                   int block_size)
+  : data_(reinterpret_cast<const uint8*>(data)),
+    size_(size),
+    block_size_(block_size > 0 ? block_size : size),
+    position_(0),
+    last_returned_size_(0) {
+}
+
+ArrayInputStream::~ArrayInputStream() {
+}
+
+bool ArrayInputStream::Next(const void** data, int* size) {
+  if (position_ < size_) {
+    last_returned_size_ = min(block_size_, size_ - position_);
+    *data = data_ + position_;
+    *size = last_returned_size_;
+    position_ += last_returned_size_;
+    return true;
+  } else {
+    // We're at the end of the array.
+    last_returned_size_ = 0;   // Don't let caller back up.
+    return false;
+  }
+}
+
+void ArrayInputStream::BackUp(int count) {
+  GOOGLE_CHECK_GT(last_returned_size_, 0)
+      << "BackUp() can only be called after a successful Next().";
+  GOOGLE_CHECK_LE(count, last_returned_size_);
+  GOOGLE_CHECK_GE(count, 0);
+  position_ -= count;
+  last_returned_size_ = 0;  // Don't let caller back up further.
+}
+
+bool ArrayInputStream::Skip(int count) {
+  GOOGLE_CHECK_GE(count, 0);
+  last_returned_size_ = 0;   // Don't let caller back up.
+  if (count > size_ - position_) {
+    position_ = size_;
+    return false;
+  } else {
+    position_ += count;
+    return true;
+  }
+}
+
+int64 ArrayInputStream::ByteCount() const {
+  return position_;
+}
+
+
+// ===================================================================
+
+ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size)
+  : data_(reinterpret_cast<uint8*>(data)),
+    size_(size),
+    block_size_(block_size > 0 ? block_size : size),
+    position_(0),
+    last_returned_size_(0) {
+}
+
+ArrayOutputStream::~ArrayOutputStream() {
+}
+
+bool ArrayOutputStream::Next(void** data, int* size) {
+  if (position_ < size_) {
+    last_returned_size_ = min(block_size_, size_ - position_);
+    *data = data_ + position_;
+    *size = last_returned_size_;
+    position_ += last_returned_size_;
+    return true;
+  } else {
+    // We're at the end of the array.
+    last_returned_size_ = 0;   // Don't let caller back up.
+    return false;
+  }
+}
+
+void ArrayOutputStream::BackUp(int count) {
+  GOOGLE_CHECK_GT(last_returned_size_, 0)
+      << "BackUp() can only be called after a successful Next().";
+  GOOGLE_CHECK_LE(count, last_returned_size_);
+  GOOGLE_CHECK_GE(count, 0);
+  position_ -= count;
+  last_returned_size_ = 0;  // Don't let caller back up further.
+}
+
+int64 ArrayOutputStream::ByteCount() const {
+  return position_;
+}
+
+// ===================================================================
+
+StringOutputStream::StringOutputStream(string* target)
+  : target_(target) {
+}
+
+StringOutputStream::~StringOutputStream() {
+}
+
+bool StringOutputStream::Next(void** data, int* size) {
+  int old_size = target_->size();
+
+  // Grow the string.
+  if (old_size < target_->capacity()) {
+    // Resize the string to match its capacity, since we can get away
+    // without a memory allocation this way.
+    target_->resize(target_->capacity());
+  } else {
+    // Size has reached capacity, so double the size.  Also make sure
+    // that the new size is at least kMinimumSize.
+    target_->resize(
+      max(old_size * 2,
+          kMinimumSize + 0));  // "+ 0" works around GCC4 weirdness.
+  }
+
+  *data = string_as_array(target_) + old_size;
+  *size = target_->size() - old_size;
+  return true;
+}
+
+void StringOutputStream::BackUp(int count) {
+  GOOGLE_CHECK_GE(count, 0);
+  GOOGLE_CHECK_LE(count, target_->size());
+  target_->resize(target_->size() - count);
+}
+
+int64 StringOutputStream::ByteCount() const {
+  return target_->size();
+}
+
+// ===================================================================
+
+
+// ===================================================================
+
+CopyingInputStream::~CopyingInputStream() {}
+
+int CopyingInputStream::Skip(int count) {
+  char junk[4096];
+  int skipped = 0;
+  while (skipped < count) {
+    int bytes = Read(junk, min(count, implicit_cast<int>(sizeof(junk))));
+    if (bytes <= 0) {
+      // EOF or read error.
+      return skipped;
+    }
+    skipped += bytes;
+  }
+  return skipped;
+}
+
+CopyingInputStreamAdaptor::CopyingInputStreamAdaptor(
+    CopyingInputStream* copying_stream, int block_size)
+  : copying_stream_(copying_stream),
+    owns_copying_stream_(false),
+    failed_(false),
+    position_(0),
+    buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
+    buffer_used_(0),
+    backup_bytes_(0) {
+}
+
+CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() {
+  if (owns_copying_stream_) {
+    delete copying_stream_;
+  }
+}
+
+bool CopyingInputStreamAdaptor::Next(const void** data, int* size) {
+  if (failed_) {
+    // Already failed on a previous read.
+    return false;
+  }
+
+  AllocateBufferIfNeeded();
+
+  if (backup_bytes_ > 0) {
+    // We have data left over from a previous BackUp(), so just return that.
+    *data = buffer_.get() + buffer_used_ - backup_bytes_;
+    *size = backup_bytes_;
+    backup_bytes_ = 0;
+    return true;
+  }
+
+  // Read new data into the buffer.
+  buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_);
+  if (buffer_used_ <= 0) {
+    // EOF or read error.  We don't need the buffer anymore.
+    if (buffer_used_ < 0) {
+      // Read error (not EOF).
+      failed_ = true;
+    }
+    FreeBuffer();
+    return false;
+  }
+  position_ += buffer_used_;
+
+  *size = buffer_used_;
+  *data = buffer_.get();
+  return true;
+}
+
+void CopyingInputStreamAdaptor::BackUp(int count) {
+  GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL)
+    << " BackUp() can only be called after Next().";
+  GOOGLE_CHECK_LE(count, buffer_used_)
+    << " Can't back up over more bytes than were returned by the last call"
+       " to Next().";
+  GOOGLE_CHECK_GE(count, 0)
+    << " Parameter to BackUp() can't be negative.";
+
+  backup_bytes_ = count;
+}
+
+bool CopyingInputStreamAdaptor::Skip(int count) {
+  GOOGLE_CHECK_GE(count, 0);
+
+  if (failed_) {
+    // Already failed on a previous read.
+    return false;
+  }
+
+  // First skip any bytes left over from a previous BackUp().
+  if (backup_bytes_ >= count) {
+    // We have more data left over than we're trying to skip.  Just chop it.
+    backup_bytes_ -= count;
+    return true;
+  }
+
+  count -= backup_bytes_;
+  backup_bytes_ = 0;
+
+  int skipped = copying_stream_->Skip(count);
+  position_ += skipped;
+  return skipped == count;
+}
+
+int64 CopyingInputStreamAdaptor::ByteCount() const {
+  return position_ - backup_bytes_;
+}
+
+void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() {
+  if (buffer_.get() == NULL) {
+    buffer_.reset(new uint8[buffer_size_]);
+  }
+}
+
+void CopyingInputStreamAdaptor::FreeBuffer() {
+  GOOGLE_CHECK_EQ(backup_bytes_, 0);
+  buffer_used_ = 0;
+  buffer_.reset();
+}
+
+// ===================================================================
+
+CopyingOutputStream::~CopyingOutputStream() {}
+
+CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor(
+    CopyingOutputStream* copying_stream, int block_size)
+  : copying_stream_(copying_stream),
+    owns_copying_stream_(false),
+    failed_(false),
+    position_(0),
+    buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
+    buffer_used_(0) {
+}
+
+CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() {
+  WriteBuffer();
+  if (owns_copying_stream_) {
+    delete copying_stream_;
+  }
+}
+
+bool CopyingOutputStreamAdaptor::Flush() {
+  return WriteBuffer();
+}
+
+bool CopyingOutputStreamAdaptor::Next(void** data, int* size) {
+  if (buffer_used_ == buffer_size_) {
+    if (!WriteBuffer()) return false;
+  }
+
+  AllocateBufferIfNeeded();
+
+  *data = buffer_.get() + buffer_used_;
+  *size = buffer_size_ - buffer_used_;
+  buffer_used_ = buffer_size_;
+  return true;
+}
+
+void CopyingOutputStreamAdaptor::BackUp(int count) {
+  GOOGLE_CHECK_GE(count, 0);
+  GOOGLE_CHECK_EQ(buffer_used_, buffer_size_)
+    << " BackUp() can only be called after Next().";
+  GOOGLE_CHECK_LE(count, buffer_used_)
+    << " Can't back up over more bytes than were returned by the last call"
+       " to Next().";
+
+  buffer_used_ -= count;
+}
+
+int64 CopyingOutputStreamAdaptor::ByteCount() const {
+  return position_ + buffer_used_;
+}
+
+bool CopyingOutputStreamAdaptor::WriteBuffer() {
+  if (failed_) {
+    // Already failed on a previous write.
+    return false;
+  }
+
+  if (buffer_used_ == 0) return true;
+
+  if (copying_stream_->Write(buffer_.get(), buffer_used_)) {
+    position_ += buffer_used_;
+    buffer_used_ = 0;
+    return true;
+  } else {
+    failed_ = true;
+    FreeBuffer();
+    return false;
+  }
+}
+
+void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() {
+  if (buffer_ == NULL) {
+    buffer_.reset(new uint8[buffer_size_]);
+  }
+}
+
+void CopyingOutputStreamAdaptor::FreeBuffer() {
+  buffer_used_ = 0;
+  buffer_.reset();
+}
+
+// ===================================================================
+
+FileInputStream::FileInputStream(int file_descriptor, int block_size)
+  : copying_input_(file_descriptor),
+    impl_(&copying_input_, block_size) {
+}
+
+FileInputStream::~FileInputStream() {}
+
+bool FileInputStream::Close() {
+  return copying_input_.Close();
+}
+
+bool FileInputStream::Next(const void** data, int* size) {
+  return impl_.Next(data, size);
+}
+
+void FileInputStream::BackUp(int count) {
+  impl_.BackUp(count);
+}
+
+bool FileInputStream::Skip(int count) {
+  return impl_.Skip(count);
+}
+
+int64 FileInputStream::ByteCount() const {
+  return impl_.ByteCount();
+}
+
+FileInputStream::CopyingFileInputStream::CopyingFileInputStream(
+    int file_descriptor)
+  : file_(file_descriptor),
+    close_on_delete_(false),
+    is_closed_(false),
+    errno_(0),
+    previous_seek_failed_(false) {
+}
+
+FileInputStream::CopyingFileInputStream::~CopyingFileInputStream() {
+  if (close_on_delete_) {
+    if (!Close()) {
+      GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_);
+    }
+  }
+}
+
+bool FileInputStream::CopyingFileInputStream::Close() {
+  GOOGLE_CHECK(!is_closed_);
+
+  is_closed_ = true;
+  if (close_no_eintr(file_) != 0) {
+    // The docs on close() do not specify whether a file descriptor is still
+    // open after close() fails with EIO.  However, the glibc source code
+    // seems to indicate that it is not.
+    errno_ = errno;
+    return false;
+  }
+
+  return true;
+}
+
+int FileInputStream::CopyingFileInputStream::Read(void* buffer, int size) {
+  GOOGLE_CHECK(!is_closed_);
+
+  int result;
+  do {
+    result = read(file_, buffer, size);
+  } while (result < 0 && errno == EINTR);
+
+  if (result < 0) {
+    // Read error (not EOF).
+    errno_ = errno;
+  }
+
+  return result;
+}
+
+int FileInputStream::CopyingFileInputStream::Skip(int count) {
+  GOOGLE_CHECK(!is_closed_);
+
+  if (!previous_seek_failed_ &&
+      lseek(file_, count, SEEK_CUR) != (off_t)-1) {
+    // Seek succeeded.
+    return count;
+  } else {
+    // Failed to seek.
+
+    // Note to self:  Don't seek again.  This file descriptor doesn't
+    // support it.
+    previous_seek_failed_ = true;
+
+    // Use the default implementation.
+    return CopyingInputStream::Skip(count);
+  }
+}
+
+// ===================================================================
+
+FileOutputStream::FileOutputStream(int file_descriptor, int block_size)
+  : copying_output_(file_descriptor),
+    impl_(&copying_output_, block_size) {
+}
+
+FileOutputStream::~FileOutputStream() {
+  impl_.Flush();
+}
+
+bool FileOutputStream::Close() {
+  bool flush_succeeded = impl_.Flush();
+  return copying_output_.Close() && flush_succeeded;
+}
+
+bool FileOutputStream::Next(void** data, int* size) {
+  return impl_.Next(data, size);
+}
+
+void FileOutputStream::BackUp(int count) {
+  impl_.BackUp(count);
+}
+
+int64 FileOutputStream::ByteCount() const {
+  return impl_.ByteCount();
+}
+
+FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream(
+    int file_descriptor)
+  : file_(file_descriptor),
+    close_on_delete_(false),
+    is_closed_(false),
+    errno_(0) {
+}
+
+FileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() {
+  if (close_on_delete_) {
+    if (!Close()) {
+      GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_);
+    }
+  }
+}
+
+bool FileOutputStream::CopyingFileOutputStream::Close() {
+  GOOGLE_CHECK(!is_closed_);
+
+  is_closed_ = true;
+  if (close_no_eintr(file_) != 0) {
+    // The docs on close() do not specify whether a file descriptor is still
+    // open after close() fails with EIO.  However, the glibc source code
+    // seems to indicate that it is not.
+    errno_ = errno;
+    return false;
+  }
+
+  return true;
+}
+
+bool FileOutputStream::CopyingFileOutputStream::Write(
+    const void* buffer, int size) {
+  GOOGLE_CHECK(!is_closed_);
+  int total_written = 0;
+
+  const uint8* buffer_base = reinterpret_cast<const uint8*>(buffer);
+
+  while (total_written < size) {
+    int bytes;
+    do {
+      bytes = write(file_, buffer_base + total_written, size - total_written);
+    } while (bytes < 0 && errno == EINTR);
+
+    if (bytes <= 0) {
+      // Write error.
+
+      // FIXME(kenton):  According to the man page, if write() returns zero,
+      //   there was no error; write() simply did not write anything.  It's
+      //   unclear under what circumstances this might happen, but presumably
+      //   errno won't be set in this case.  I am confused as to how such an
+      //   event should be handled.  For now I'm treating it as an error, since
+      //   retrying seems like it could lead to an infinite loop.  I suspect
+      //   this never actually happens anyway.
+
+      if (bytes < 0) {
+        errno_ = errno;
+      }
+      return false;
+    }
+    total_written += bytes;
+  }
+
+  return true;
+}
+
+// ===================================================================
+
+IstreamInputStream::IstreamInputStream(istream* input, int block_size)
+  : copying_input_(input),
+    impl_(&copying_input_, block_size) {
+}
+
+IstreamInputStream::~IstreamInputStream() {}
+
+bool IstreamInputStream::Next(const void** data, int* size) {
+  return impl_.Next(data, size);
+}
+
+void IstreamInputStream::BackUp(int count) {
+  impl_.BackUp(count);
+}
+
+bool IstreamInputStream::Skip(int count) {
+  return impl_.Skip(count);
+}
+
+int64 IstreamInputStream::ByteCount() const {
+  return impl_.ByteCount();
+}
+
+IstreamInputStream::CopyingIstreamInputStream::CopyingIstreamInputStream(
+    istream* input)
+  : input_(input) {
+}
+
+IstreamInputStream::CopyingIstreamInputStream::~CopyingIstreamInputStream() {}
+
+int IstreamInputStream::CopyingIstreamInputStream::Read(
+    void* buffer, int size) {
+  input_->read(reinterpret_cast<char*>(buffer), size);
+  int result = input_->gcount();
+  if (result == 0 && input_->fail() && !input_->eof()) {
+    return -1;
+  }
+  return result;
+}
+
+// ===================================================================
+
+OstreamOutputStream::OstreamOutputStream(ostream* output, int block_size)
+  : copying_output_(output),
+    impl_(&copying_output_, block_size) {
+}
+
+OstreamOutputStream::~OstreamOutputStream() {
+  impl_.Flush();
+}
+
+bool OstreamOutputStream::Next(void** data, int* size) {
+  return impl_.Next(data, size);
+}
+
+void OstreamOutputStream::BackUp(int count) {
+  impl_.BackUp(count);
+}
+
+int64 OstreamOutputStream::ByteCount() const {
+  return impl_.ByteCount();
+}
+
+OstreamOutputStream::CopyingOstreamOutputStream::CopyingOstreamOutputStream(
+    ostream* output)
+  : output_(output) {
+}
+
+OstreamOutputStream::CopyingOstreamOutputStream::~CopyingOstreamOutputStream() {
+}
+
+bool OstreamOutputStream::CopyingOstreamOutputStream::Write(
+    const void* buffer, int size) {
+  output_->write(reinterpret_cast<const char*>(buffer), size);
+  return output_->good();
+}
+
+// ===================================================================
+
+ConcatenatingInputStream::ConcatenatingInputStream(
+    ZeroCopyInputStream* const streams[], int count)
+  : streams_(streams), stream_count_(count), bytes_retired_(0) {
+}
+
+ConcatenatingInputStream::~ConcatenatingInputStream() {
+}
+
+bool ConcatenatingInputStream::Next(const void** data, int* size) {
+  while (stream_count_ > 0) {
+    if (streams_[0]->Next(data, size)) return true;
+
+    // That stream is done.  Advance to the next one.
+    bytes_retired_ += streams_[0]->ByteCount();
+    ++streams_;
+    --stream_count_;
+  }
+
+  // No more streams.
+  return false;
+}
+
+void ConcatenatingInputStream::BackUp(int count) {
+  if (stream_count_ > 0) {
+    streams_[0]->BackUp(count);
+  } else {
+    GOOGLE_LOG(DFATAL) << "Can't BackUp() after failed Next().";
+  }
+}
+
+bool ConcatenatingInputStream::Skip(int count) {
+  while (stream_count_ > 0) {
+    // Assume that ByteCount() can be used to find out how much we actually
+    // skipped when Skip() fails.
+    int64 target_byte_count = streams_[0]->ByteCount() + count;
+    if (streams_[0]->Skip(count)) return true;
+
+    // Hit the end of the stream.  Figure out how many more bytes we still have
+    // to skip.
+    int64 final_byte_count = streams_[0]->ByteCount();
+    GOOGLE_DCHECK_LT(final_byte_count, target_byte_count);
+    count = target_byte_count - final_byte_count;
+
+    // That stream is done.  Advance to the next one.
+    bytes_retired_ += final_byte_count;
+    ++streams_;
+    --stream_count_;
+  }
+
+  return false;
+}
+
+int64 ConcatenatingInputStream::ByteCount() const {
+  if (stream_count_ == 0) {
+    return bytes_retired_;
+  } else {
+    return bytes_retired_ + streams_[0]->ByteCount();
+  }
+}
+
+
+// ===================================================================
+
+LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input,
+                                         int64 limit)
+  : input_(input), limit_(limit) {}
+
+LimitingInputStream::~LimitingInputStream() {
+  // If we overshot the limit, back up.
+  if (limit_ < 0) input_->BackUp(-limit_);
+}
+
+bool LimitingInputStream::Next(const void** data, int* size) {
+  if (limit_ < 0) return false;
+  if (!input_->Next(data, size)) return false;
+
+  limit_ -= *size;
+  if (limit_ < 0) {
+    // We overshot the limit.  Reduce *size to hide the rest of the buffer.
+    *size += limit_;
+  }
+  return true;
+}
+
+void LimitingInputStream::BackUp(int count) {
+  if (limit_ < 0) {
+    input_->BackUp(count - limit_);
+    limit_ = count;
+  } else {
+    input_->BackUp(count);
+    limit_ += count;
+  }
+}
+
+bool LimitingInputStream::Skip(int count) {
+  if (count > limit_) {
+    if (limit_ < 0) return false;
+    input_->Skip(limit_);
+    limit_ = 0;
+    return false;
+  } else {
+    if (!input_->Skip(count)) return false;
+    limit_ -= count;
+    return true;
+  }
+}
+
+int64 LimitingInputStream::ByteCount() const {
+  if (limit_ < 0) {
+    return input_->ByteCount() + limit_;
+  } else {
+    return input_->ByteCount();
+  }
+}
+
+
+// ===================================================================
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h
new file mode 100644
index 0000000..bd73afb
--- /dev/null
+++ b/src/google/protobuf/io/zero_copy_stream_impl.h
@@ -0,0 +1,617 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains common implementations of the interfaces defined in
+// zero_copy_stream.h.  These implementations cover I/O on raw arrays,
+// strings, and file descriptors.  Of course, many users will probably
+// want to write their own implementations of these interfaces specific
+// to the particular I/O abstractions they prefer to use, but these
+// should cover the most common cases.
+
+#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
+#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
+
+#include <string>
+#include <iosfwd>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/common.h>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// ===================================================================
+
+// A ZeroCopyInputStream backed by an in-memory array of bytes.
+class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
+ public:
+  // Create an InputStream that returns the bytes pointed to by "data".
+  // "data" remains the property of the caller but must remain valid until
+  // the stream is destroyed.  If a block_size is given, calls to Next()
+  // will return data blocks no larger than the given size.  Otherwise, the
+  // first call to Next() returns the entire array.  block_size is mainly
+  // useful for testing; in production you would probably never want to set
+  // it.
+  ArrayInputStream(const void* data, int size, int block_size = -1);
+  ~ArrayInputStream();
+
+  // implements ZeroCopyInputStream ----------------------------------
+  bool Next(const void** data, int* size);
+  void BackUp(int count);
+  bool Skip(int count);
+  int64 ByteCount() const;
+
+
+ private:
+  const uint8* const data_;  // The byte array.
+  const int size_;           // Total size of the array.
+  const int block_size_;     // How many bytes to return at a time.
+
+  int position_;
+  int last_returned_size_;   // How many bytes we returned last time Next()
+                             // was called (used for error checking only).
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream backed by an in-memory array of bytes.
+class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream {
+ public:
+  // Create an OutputStream that writes to the bytes pointed to by "data".
+  // "data" remains the property of the caller but must remain valid until
+  // the stream is destroyed.  If a block_size is given, calls to Next()
+  // will return data blocks no larger than the given size.  Otherwise, the
+  // first call to Next() returns the entire array.  block_size is mainly
+  // useful for testing; in production you would probably never want to set
+  // it.
+  ArrayOutputStream(void* data, int size, int block_size = -1);
+  ~ArrayOutputStream();
+
+  // implements ZeroCopyOutputStream ---------------------------------
+  bool Next(void** data, int* size);
+  void BackUp(int count);
+  int64 ByteCount() const;
+
+ private:
+  uint8* const data_;        // The byte array.
+  const int size_;           // Total size of the array.
+  const int block_size_;     // How many bytes to return at a time.
+
+  int position_;
+  int last_returned_size_;   // How many bytes we returned last time Next()
+                             // was called (used for error checking only).
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream which appends bytes to a string.
+class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
+ public:
+  // Create a StringOutputStream which appends bytes to the given string.
+  // The string remains property of the caller, but it MUST NOT be accessed
+  // in any way until the stream is destroyed.
+  //
+  // Hint:  If you call target->reserve(n) before creating the stream,
+  //   the first call to Next() will return at least n bytes of buffer
+  //   space.
+  explicit StringOutputStream(string* target);
+  ~StringOutputStream();
+
+  // implements ZeroCopyOutputStream ---------------------------------
+  bool Next(void** data, int* size);
+  void BackUp(int count);
+  int64 ByteCount() const;
+
+ private:
+  static const int kMinimumSize = 16;
+
+  string* target_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream);
+};
+
+// Note:  There is no StringInputStream.  Instead, just create an
+// ArrayInputStream as follows:
+//   ArrayInputStream input(str.data(), str.size());
+
+// ===================================================================
+
+
+// ===================================================================
+
+// A generic traditional input stream interface.
+//
+// Lots of traditional input streams (e.g. file descriptors, C stdio
+// streams, and C++ iostreams) expose an interface where every read
+// involves copying bytes into a buffer.  If you want to take such an
+// interface and make a ZeroCopyInputStream based on it, simply implement
+// CopyingInputStream and then use CopyingInputStreamAdaptor.
+//
+// CopyingInputStream implementations should avoid buffering if possible.
+// CopyingInputStreamAdaptor does its own buffering and will read data
+// in large blocks.
+class LIBPROTOBUF_EXPORT CopyingInputStream {
+ public:
+  virtual ~CopyingInputStream();
+
+  // Reads up to "size" bytes into the given buffer.  Returns the number of
+  // bytes read.  Read() waits until at least one byte is available, or
+  // returns zero if no bytes will ever become available (EOF), or -1 if a
+  // permanent read error occurred.
+  virtual int Read(void* buffer, int size) = 0;
+
+  // Skips the next "count" bytes of input.  Returns the number of bytes
+  // actually skipped.  This will always be exactly equal to "count" unless
+  // EOF was reached or a permanent read error occurred.
+  //
+  // The default implementation just repeatedly calls Read() into a scratch
+  // buffer.
+  virtual int Skip(int count);
+};
+
+// A ZeroCopyInputStream which reads from a CopyingInputStream.  This is
+// useful for implementing ZeroCopyInputStreams that read from traditional
+// streams.  Note that this class is not really zero-copy.
+//
+// If you want to read from file descriptors or C++ istreams, this is
+// already implemented for you:  use FileInputStream or IstreamInputStream
+// respectively.
+class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream {
+ public:
+  // Creates a stream that reads from the given CopyingInputStream.
+  // If a block_size is given, it specifies the number of bytes that
+  // should be read and returned with each call to Next().  Otherwise,
+  // a reasonable default is used.  The caller retains ownership of
+  // copying_stream unless SetOwnsCopyingStream(true) is called.
+  explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream,
+                                     int block_size = -1);
+  ~CopyingInputStreamAdaptor();
+
+  // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to
+  // delete the underlying CopyingInputStream when it is destroyed.
+  void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
+
+  // implements ZeroCopyInputStream ----------------------------------
+  bool Next(const void** data, int* size);
+  void BackUp(int count);
+  bool Skip(int count);
+  int64 ByteCount() const;
+
+ private:
+  // Insures that buffer_ is not NULL.
+  void AllocateBufferIfNeeded();
+  // Frees the buffer and resets buffer_used_.
+  void FreeBuffer();
+
+  // The underlying copying stream.
+  CopyingInputStream* copying_stream_;
+  bool owns_copying_stream_;
+
+  // True if we have seen a permenant error from the underlying stream.
+  bool failed_;
+
+  // The current position of copying_stream_, relative to the point where
+  // we started reading.
+  int64 position_;
+
+  // Data is read into this buffer.  It may be NULL if no buffer is currently
+  // in use.  Otherwise, it points to an array of size buffer_size_.
+  scoped_array<uint8> buffer_;
+  const int buffer_size_;
+
+  // Number of valid bytes currently in the buffer (i.e. the size last
+  // returned by Next()).  0 <= buffer_used_ <= buffer_size_.
+  int buffer_used_;
+
+  // Number of bytes in the buffer which were backed up over by a call to
+  // BackUp().  These need to be returned again.
+  // 0 <= backup_bytes_ <= buffer_used_
+  int backup_bytes_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor);
+};
+
+// ===================================================================
+
+// A generic traditional output stream interface.
+//
+// Lots of traditional output streams (e.g. file descriptors, C stdio
+// streams, and C++ iostreams) expose an interface where every write
+// involves copying bytes from a buffer.  If you want to take such an
+// interface and make a ZeroCopyOutputStream based on it, simply implement
+// CopyingOutputStream and then use CopyingOutputStreamAdaptor.
+//
+// CopyingOutputStream implementations should avoid buffering if possible.
+// CopyingOutputStreamAdaptor does its own buffering and will write data
+// in large blocks.
+class LIBPROTOBUF_EXPORT CopyingOutputStream {
+ public:
+  virtual ~CopyingOutputStream();
+
+  // Writes "size" bytes from the given buffer to the output.  Returns true
+  // if successful, false on a write error.
+  virtual bool Write(const void* buffer, int size) = 0;
+};
+
+// A ZeroCopyOutputStream which writes to a CopyingOutputStream.  This is
+// useful for implementing ZeroCopyOutputStreams that write to traditional
+// streams.  Note that this class is not really zero-copy.
+//
+// If you want to write to file descriptors or C++ ostreams, this is
+// already implemented for you:  use FileOutputStream or OstreamOutputStream
+// respectively.
+class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream {
+ public:
+  // Creates a stream that writes to the given Unix file descriptor.
+  // If a block_size is given, it specifies the size of the buffers
+  // that should be returned by Next().  Otherwise, a reasonable default
+  // is used.
+  explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream,
+                                      int block_size = -1);
+  ~CopyingOutputStreamAdaptor();
+
+  // Writes all pending data to the underlying stream.  Returns false if a
+  // write error occurred on the underlying stream.  (The underlying
+  // stream itself is not necessarily flushed.)
+  bool Flush();
+
+  // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to
+  // delete the underlying CopyingOutputStream when it is destroyed.
+  void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
+
+  // implements ZeroCopyOutputStream ---------------------------------
+  bool Next(void** data, int* size);
+  void BackUp(int count);
+  int64 ByteCount() const;
+
+ private:
+  // Write the current buffer, if it is present.
+  bool WriteBuffer();
+  // Insures that buffer_ is not NULL.
+  void AllocateBufferIfNeeded();
+  // Frees the buffer.
+  void FreeBuffer();
+
+  // The underlying copying stream.
+  CopyingOutputStream* copying_stream_;
+  bool owns_copying_stream_;
+
+  // True if we have seen a permenant error from the underlying stream.
+  bool failed_;
+
+  // The current position of copying_stream_, relative to the point where
+  // we started writing.
+  int64 position_;
+
+  // Data is written from this buffer.  It may be NULL if no buffer is
+  // currently in use.  Otherwise, it points to an array of size buffer_size_.
+  scoped_array<uint8> buffer_;
+  const int buffer_size_;
+
+  // Number of valid bytes currently in the buffer (i.e. the size last
+  // returned by Next()).  When BackUp() is called, we just reduce this.
+  // 0 <= buffer_used_ <= buffer_size_.
+  int buffer_used_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor);
+};
+
+// ===================================================================
+
+// A ZeroCopyInputStream which reads from a file descriptor.
+//
+// FileInputStream is preferred over using an ifstream with IstreamInputStream.
+// The latter will introduce an extra layer of buffering, harming performance.
+// Also, it's conceivable that FileInputStream could someday be enhanced
+// to use zero-copy file descriptors on OSs which support them.
+class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
+ public:
+  // Creates a stream that reads from the given Unix file descriptor.
+  // If a block_size is given, it specifies the number of bytes that
+  // should be read and returned with each call to Next().  Otherwise,
+  // a reasonable default is used.
+  explicit FileInputStream(int file_descriptor, int block_size = -1);
+  ~FileInputStream();
+
+  // Flushes any buffers and closes the underlying file.  Returns false if
+  // an error occurs during the process; use GetErrno() to examine the error.
+  // Even if an error occurs, the file descriptor is closed when this returns.
+  bool Close();
+
+  // By default, the file descriptor is not closed when the stream is
+  // destroyed.  Call SetCloseOnDelete(true) to change that.  WARNING:
+  // This leaves no way for the caller to detect if close() fails.  If
+  // detecting close() errors is important to you, you should arrange
+  // to close the descriptor yourself.
+  void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); }
+
+  // If an I/O error has occurred on this file descriptor, this is the
+  // errno from that error.  Otherwise, this is zero.  Once an error
+  // occurs, the stream is broken and all subsequent operations will
+  // fail.
+  int GetErrno() { return copying_input_.GetErrno(); }
+
+  // implements ZeroCopyInputStream ----------------------------------
+  bool Next(const void** data, int* size);
+  void BackUp(int count);
+  bool Skip(int count);
+  int64 ByteCount() const;
+
+ private:
+  class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
+   public:
+    CopyingFileInputStream(int file_descriptor);
+    ~CopyingFileInputStream();
+
+    bool Close();
+    void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
+    int GetErrno() { return errno_; }
+
+    // implements CopyingInputStream ---------------------------------
+    int Read(void* buffer, int size);
+    int Skip(int count);
+
+   private:
+    // The file descriptor.
+    const int file_;
+    bool close_on_delete_;
+    bool is_closed_;
+
+    // The errno of the I/O error, if one has occurred.  Otherwise, zero.
+    int errno_;
+
+    // Did we try to seek once and fail?  If so, we assume this file descriptor
+    // doesn't support seeking and won't try again.
+    bool previous_seek_failed_;
+
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream);
+  };
+
+  CopyingFileInputStream copying_input_;
+  CopyingInputStreamAdaptor impl_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream which writes to a file descriptor.
+//
+// FileInputStream is preferred over using an ofstream with OstreamOutputStream.
+// The latter will introduce an extra layer of buffering, harming performance.
+// Also, it's conceivable that FileInputStream could someday be enhanced
+// to use zero-copy file descriptors on OSs which support them.
+class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream {
+ public:
+  // Creates a stream that writes to the given Unix file descriptor.
+  // If a block_size is given, it specifies the size of the buffers
+  // that should be returned by Next().  Otherwise, a reasonable default
+  // is used.
+  explicit FileOutputStream(int file_descriptor, int block_size = -1);
+  ~FileOutputStream();
+
+  // Flushes any buffers and closes the underlying file.  Returns false if
+  // an error occurs during the process; use GetErrno() to examine the error.
+  // Even if an error occurs, the file descriptor is closed when this returns.
+  bool Close();
+
+  // By default, the file descriptor is not closed when the stream is
+  // destroyed.  Call SetCloseOnDelete(true) to change that.  WARNING:
+  // This leaves no way for the caller to detect if close() fails.  If
+  // detecting close() errors is important to you, you should arrange
+  // to close the descriptor yourself.
+  void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); }
+
+  // If an I/O error has occurred on this file descriptor, this is the
+  // errno from that error.  Otherwise, this is zero.  Once an error
+  // occurs, the stream is broken and all subsequent operations will
+  // fail.
+  int GetErrno() { return copying_output_.GetErrno(); }
+
+  // implements ZeroCopyOutputStream ---------------------------------
+  bool Next(void** data, int* size);
+  void BackUp(int count);
+  int64 ByteCount() const;
+
+ private:
+  class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
+   public:
+    CopyingFileOutputStream(int file_descriptor);
+    ~CopyingFileOutputStream();
+
+    bool Close();
+    void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
+    int GetErrno() { return errno_; }
+
+    // implements CopyingOutputStream --------------------------------
+    bool Write(const void* buffer, int size);
+
+   private:
+    // The file descriptor.
+    const int file_;
+    bool close_on_delete_;
+    bool is_closed_;
+
+    // The errno of the I/O error, if one has occurred.  Otherwise, zero.
+    int errno_;
+
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream);
+  };
+
+  CopyingFileOutputStream copying_output_;
+  CopyingOutputStreamAdaptor impl_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyInputStream which reads from a C++ istream.
+//
+// Note that for reading files (or anything represented by a file descriptor),
+// FileInputStream is more efficient.
+class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
+ public:
+  // Creates a stream that reads from the given C++ istream.
+  // If a block_size is given, it specifies the number of bytes that
+  // should be read and returned with each call to Next().  Otherwise,
+  // a reasonable default is used.
+  explicit IstreamInputStream(istream* stream, int block_size = -1);
+  ~IstreamInputStream();
+
+  // implements ZeroCopyInputStream ----------------------------------
+  bool Next(const void** data, int* size);
+  void BackUp(int count);
+  bool Skip(int count);
+  int64 ByteCount() const;
+
+ private:
+  class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
+   public:
+    CopyingIstreamInputStream(istream* input);
+    ~CopyingIstreamInputStream();
+
+    // implements CopyingInputStream ---------------------------------
+    int Read(void* buffer, int size);
+    // (We use the default implementation of Skip().)
+
+   private:
+    // The stream.
+    istream* input_;
+
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream);
+  };
+
+  CopyingIstreamInputStream copying_input_;
+  CopyingInputStreamAdaptor impl_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream which writes to a C++ ostream.
+//
+// Note that for writing files (or anything represented by a file descriptor),
+// FileOutputStream is more efficient.
+class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
+ public:
+  // Creates a stream that writes to the given C++ ostream.
+  // If a block_size is given, it specifies the size of the buffers
+  // that should be returned by Next().  Otherwise, a reasonable default
+  // is used.
+  explicit OstreamOutputStream(ostream* stream, int block_size = -1);
+  ~OstreamOutputStream();
+
+  // implements ZeroCopyOutputStream ---------------------------------
+  bool Next(void** data, int* size);
+  void BackUp(int count);
+  int64 ByteCount() const;
+
+ private:
+  class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream {
+   public:
+    CopyingOstreamOutputStream(ostream* output);
+    ~CopyingOstreamOutputStream();
+
+    // implements CopyingOutputStream --------------------------------
+    bool Write(const void* buffer, int size);
+
+   private:
+    // The stream.
+    ostream* output_;
+
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream);
+  };
+
+  CopyingOstreamOutputStream copying_output_;
+  CopyingOutputStreamAdaptor impl_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyInputStream which reads from several other streams in sequence.
+// ConcatenatingInputStream is unable to distinguish between end-of-stream
+// and read errors in the underlying streams, so it assumes any errors mean
+// end-of-stream.  So, if the underlying streams fail for any other reason,
+// ConcatenatingInputStream may do odd things.  It is suggested that you do
+// not use ConcatenatingInputStream on streams that might produce read errors
+// other than end-of-stream.
+class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
+ public:
+  // All streams passed in as well as the array itself must remain valid
+  // until the ConcatenatingInputStream is destroyed.
+  ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
+  ~ConcatenatingInputStream();
+
+  // implements ZeroCopyInputStream ----------------------------------
+  bool Next(const void** data, int* size);
+  void BackUp(int count);
+  bool Skip(int count);
+  int64 ByteCount() const;
+
+
+ private:
+  // As streams are retired, streams_ is incremented and count_ is
+  // decremented.
+  ZeroCopyInputStream* const* streams_;
+  int stream_count_;
+  int64 bytes_retired_;  // Bytes read from previous streams.
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyInputStream which wraps some other stream and limits it to
+// a particular byte count.
+class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
+ public:
+  LimitingInputStream(ZeroCopyInputStream* input, int64 limit);
+  ~LimitingInputStream();
+
+  // implements ZeroCopyInputStream ----------------------------------
+  bool Next(const void** data, int* size);
+  void BackUp(int count);
+  bool Skip(int count);
+  int64 ByteCount() const;
+
+
+ private:
+  ZeroCopyInputStream* input_;
+  int64 limit_;  // Decreases as we go, becomes negative if we overshoot.
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
+};
+
+// ===================================================================
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc
new file mode 100644
index 0000000..c618041
--- /dev/null
+++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -0,0 +1,443 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Testing strategy:  For each type of I/O (array, string, file, etc.) we
+// create an output stream and write some data to it, then create a
+// corresponding input stream to read the same data back and expect it to
+// match.  When the data is written, it is written in several small chunks
+// of varying sizes, with a BackUp() after each chunk.  It is read back
+// similarly, but with chunks separated at different points.  The whole
+// process is run with a variety of block sizes for both the input and
+// the output.
+//
+// TODO(kenton):  Rewrite this test to bring it up to the standards of all
+//   the other proto2 tests.  May want to wait for gTest to implement
+//   "parametized tests" so that one set of tests can be used on all the
+//   implementations.
+
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sstream>
+
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+#ifdef _WIN32
+#define pipe(fds) _pipe(fds, 4096, O_BINARY)
+#endif
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0     // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+class IoTest : public testing::Test {
+ protected:
+  // Test helpers.
+
+  // Helper to write an array of data to an output stream.
+  bool WriteToOutput(ZeroCopyOutputStream* output, const void* data, int size);
+  // Helper to read a fixed-length array of data from an input stream.
+  int ReadFromInput(ZeroCopyInputStream* input, void* data, int size);
+  // Write a string to the output stream.
+  void WriteString(ZeroCopyOutputStream* output, const char* str);
+  // Read a number of bytes equal to the size of the given string and checks
+  // that it matches the string.
+  void ReadString(ZeroCopyInputStream* input, const char* str);
+  // Writes some text to the output stream in a particular order.  Returns
+  // the number of bytes written, incase the caller needs that to set up an
+  // input stream.
+  int WriteStuff(ZeroCopyOutputStream* output);
+  // Reads text from an input stream and expects it to match what
+  // WriteStuff() writes.
+  void ReadStuff(ZeroCopyInputStream* input);
+
+  static const int kBlockSizes[];
+  static const int kBlockSizeCount;
+};
+
+const int IoTest::kBlockSizes[] = {-1, 1, 2, 5, 7, 10, 23, 64};
+const int IoTest::kBlockSizeCount = GOOGLE_ARRAYSIZE(IoTest::kBlockSizes);
+
+bool IoTest::WriteToOutput(ZeroCopyOutputStream* output,
+                           const void* data, int size) {
+  const uint8* in = reinterpret_cast<const uint8*>(data);
+  int in_size = size;
+
+  void* out;
+  int out_size;
+
+  while (true) {
+    if (!output->Next(&out, &out_size)) {
+      return false;
+    }
+
+    if (in_size <= out_size) {
+      memcpy(out, in, in_size);
+      output->BackUp(out_size - in_size);
+      return true;
+    }
+
+    memcpy(out, in, out_size);
+    in += out_size;
+    in_size -= out_size;
+  }
+}
+
+int IoTest::ReadFromInput(ZeroCopyInputStream* input, void* data, int size) {
+  uint8* out = reinterpret_cast<uint8*>(data);
+  int out_size = size;
+
+  const void* in;
+  int in_size = 0;
+
+  while (true) {
+    if (!input->Next(&in, &in_size)) {
+      return size - out_size;
+    }
+
+    if (out_size <= in_size) {
+      memcpy(out, in, out_size);
+      input->BackUp(in_size - out_size);
+      return size;  // Copied all of it.
+    }
+
+    memcpy(out, in, in_size);
+    out += in_size;
+    out_size -= in_size;
+  }
+}
+
+void IoTest::WriteString(ZeroCopyOutputStream* output, const char* str) {
+  EXPECT_TRUE(WriteToOutput(output, str, strlen(str)));
+}
+
+void IoTest::ReadString(ZeroCopyInputStream* input, const char* str) {
+  int length = strlen(str);
+  scoped_array<char> buffer(new char[length + 1]);
+  buffer[length] = '\0';
+  EXPECT_EQ(ReadFromInput(input, buffer.get(), length), length);
+  EXPECT_STREQ(str, buffer.get());
+}
+
+int IoTest::WriteStuff(ZeroCopyOutputStream* output) {
+  WriteString(output, "Hello world!\n");
+  WriteString(output, "Some te");
+  WriteString(output, "xt.  Blah blah.");
+  WriteString(output, "abcdefg");
+  WriteString(output, "01234567890123456789");
+  WriteString(output, "foobar");
+
+  EXPECT_EQ(output->ByteCount(), 68);
+
+  int result = output->ByteCount();
+  return result;
+}
+
+// Reads text from an input stream and expects it to match what WriteStuff()
+// writes.
+void IoTest::ReadStuff(ZeroCopyInputStream* input) {
+  ReadString(input, "Hello world!\n");
+  ReadString(input, "Some text.  ");
+  ReadString(input, "Blah ");
+  ReadString(input, "blah.");
+  ReadString(input, "abcdefg");
+  EXPECT_TRUE(input->Skip(20));
+  ReadString(input, "foo");
+  ReadString(input, "bar");
+
+  EXPECT_EQ(input->ByteCount(), 68);
+
+  uint8 byte;
+  EXPECT_EQ(ReadFromInput(input, &byte, 1), 0);
+}
+
+// ===================================================================
+
+TEST_F(IoTest, ArrayIo) {
+  const int kBufferSize = 256;
+  uint8 buffer[kBufferSize];
+
+  for (int i = 0; i < kBlockSizeCount; i++) {
+    for (int j = 0; j < kBlockSizeCount; j++) {
+      int size;
+      {
+        ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+        size = WriteStuff(&output);
+      }
+      {
+        ArrayInputStream input(buffer, size, kBlockSizes[j]);
+        ReadStuff(&input);
+      }
+    }
+  }
+}
+
+// There is no string input, only string output.  Also, it doesn't support
+// explicit block sizes.  So, we'll only run one test and we'll use
+// ArrayInput to read back the results.
+TEST_F(IoTest, StringIo) {
+  string str;
+  {
+    StringOutputStream output(&str);
+    WriteStuff(&output);
+  }
+  {
+    ArrayInputStream input(str.data(), str.size());
+    ReadStuff(&input);
+  }
+}
+
+
+// To test files, we create a temporary file, write, read, truncate, repeat.
+TEST_F(IoTest, FileIo) {
+  string filename = TestTempDir() + "/zero_copy_stream_test_file";
+
+  for (int i = 0; i < kBlockSizeCount; i++) {
+    for (int j = 0; j < kBlockSizeCount; j++) {
+      // Make a temporary file.
+      int file =
+        open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777);
+      ASSERT_GE(file, 0);
+
+      {
+        FileOutputStream output(file, kBlockSizes[i]);
+        WriteStuff(&output);
+        EXPECT_EQ(0, output.GetErrno());
+      }
+
+      // Rewind.
+      ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1);
+
+      {
+        FileInputStream input(file, kBlockSizes[j]);
+        ReadStuff(&input);
+        EXPECT_EQ(0, input.GetErrno());
+      }
+
+      close(file);
+    }
+  }
+}
+
+// MSVC raises various debugging exceptions if we try to use a file
+// descriptor of -1, defeating our tests below.  This class will disable
+// these debug assertions while in scope.
+class MsvcDebugDisabler {
+ public:
+#ifdef _MSC_VER
+  MsvcDebugDisabler() {
+    old_handler_ = _set_invalid_parameter_handler(MyHandler);
+    old_mode_ = _CrtSetReportMode(_CRT_ASSERT, 0);
+  }
+  ~MsvcDebugDisabler() {
+    old_handler_ = _set_invalid_parameter_handler(old_handler_);
+    old_mode_ = _CrtSetReportMode(_CRT_ASSERT, old_mode_);
+  }
+
+  static void MyHandler(const wchar_t *expr,
+                        const wchar_t *func,
+                        const wchar_t *file,
+                        unsigned int line,
+                        uintptr_t pReserved) {
+    // do nothing
+  }
+
+  _invalid_parameter_handler old_handler_;
+  int old_mode_;
+#else
+  // Dummy constructor and destructor to ensure that GCC doesn't complain
+  // that debug_disabler is an unused variable.
+  MsvcDebugDisabler() {}
+  ~MsvcDebugDisabler() {}
+#endif
+};
+
+// Test that FileInputStreams report errors correctly.
+TEST_F(IoTest, FileReadError) {
+  MsvcDebugDisabler debug_disabler;
+
+  // -1 = invalid file descriptor.
+  FileInputStream input(-1);
+
+  const void* buffer;
+  int size;
+  EXPECT_FALSE(input.Next(&buffer, &size));
+  EXPECT_EQ(EBADF, input.GetErrno());
+}
+
+// Test that FileOutputStreams report errors correctly.
+TEST_F(IoTest, FileWriteError) {
+  MsvcDebugDisabler debug_disabler;
+
+  // -1 = invalid file descriptor.
+  FileOutputStream input(-1);
+
+  void* buffer;
+  int size;
+
+  // The first call to Next() succeeds because it doesn't have anything to
+  // write yet.
+  EXPECT_TRUE(input.Next(&buffer, &size));
+
+  // Second call fails.
+  EXPECT_FALSE(input.Next(&buffer, &size));
+
+  EXPECT_EQ(EBADF, input.GetErrno());
+}
+
+// Pipes are not seekable, so File{Input,Output}Stream ends up doing some
+// different things to handle them.  We'll test by writing to a pipe and
+// reading back from it.
+TEST_F(IoTest, PipeIo) {
+  int files[2];
+
+  for (int i = 0; i < kBlockSizeCount; i++) {
+    for (int j = 0; j < kBlockSizeCount; j++) {
+      // Need to create a new pipe each time because ReadStuff() expects
+      // to see EOF at the end.
+      ASSERT_EQ(pipe(files), 0);
+
+      {
+        FileOutputStream output(files[1], kBlockSizes[i]);
+        WriteStuff(&output);
+        EXPECT_EQ(0, output.GetErrno());
+      }
+      close(files[1]);  // Send EOF.
+
+      {
+        FileInputStream input(files[0], kBlockSizes[j]);
+        ReadStuff(&input);
+        EXPECT_EQ(0, input.GetErrno());
+      }
+      close(files[0]);
+    }
+  }
+}
+
+// Test using C++ iostreams.
+TEST_F(IoTest, IostreamIo) {
+  for (int i = 0; i < kBlockSizeCount; i++) {
+    for (int j = 0; j < kBlockSizeCount; j++) {
+      stringstream stream;
+
+      {
+        OstreamOutputStream output(&stream, kBlockSizes[i]);
+        WriteStuff(&output);
+        EXPECT_FALSE(stream.fail());
+      }
+
+      {
+        IstreamInputStream input(&stream, kBlockSizes[j]);
+        ReadStuff(&input);
+        EXPECT_TRUE(stream.eof());
+      }
+    }
+  }
+}
+
+// To test ConcatenatingInputStream, we create several ArrayInputStreams
+// covering a buffer and then concatenate them.
+TEST_F(IoTest, ConcatenatingInputStream) {
+  const int kBufferSize = 256;
+  uint8 buffer[kBufferSize];
+
+  // Fill the buffer.
+  ArrayOutputStream output(buffer, kBufferSize);
+  WriteStuff(&output);
+
+  // Now split it up into multiple streams of varying sizes.
+  ASSERT_EQ(68, output.ByteCount());  // Test depends on this.
+  ArrayInputStream input1(buffer     , 12);
+  ArrayInputStream input2(buffer + 12,  7);
+  ArrayInputStream input3(buffer + 19,  6);
+  ArrayInputStream input4(buffer + 25, 15);
+  ArrayInputStream input5(buffer + 40,  0);
+  // Note:  We want to make sure we have a stream boundary somewhere between
+  // bytes 42 and 62, which is the range that it Skip()ed by ReadStuff().  This
+  // tests that a bug that existed in the original code for Skip() is fixed.
+  ArrayInputStream input6(buffer + 40, 10);
+  ArrayInputStream input7(buffer + 50, 18);  // Total = 68 bytes.
+
+  ZeroCopyInputStream* streams[] =
+    {&input1, &input2, &input3, &input4, &input5, &input6, &input7};
+
+  // Create the concatenating stream and read.
+  ConcatenatingInputStream input(streams, GOOGLE_ARRAYSIZE(streams));
+  ReadStuff(&input);
+}
+
+// To test LimitingInputStream, we write our golden text to a buffer, then
+// create an ArrayInputStream that contains the whole buffer (not just the
+// bytes written), then use a LimitingInputStream to limit it just to the
+// bytes written.
+TEST_F(IoTest, LimitingInputStream) {
+  const int kBufferSize = 256;
+  uint8 buffer[kBufferSize];
+
+  // Fill the buffer.
+  ArrayOutputStream output(buffer, kBufferSize);
+  WriteStuff(&output);
+
+  // Set up input.
+  ArrayInputStream array_input(buffer, kBufferSize);
+  LimitingInputStream input(&array_input, output.ByteCount());
+
+  ReadStuff(&input);
+}
+
+// Check that a zero-size array doesn't confuse the code.
+TEST(ZeroSizeArray, Input) {
+  ArrayInputStream input(NULL, 0);
+  const void* data;
+  int size;
+  EXPECT_FALSE(input.Next(&data, &size));
+}
+
+TEST(ZeroSizeArray, Output) {
+  ArrayOutputStream output(NULL, 0);
+  void* data;
+  int size;
+  EXPECT_FALSE(output.Next(&data, &size));
+}
+
+}  // namespace
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
new file mode 100644
index 0000000..f740ef1
--- /dev/null
+++ b/src/google/protobuf/message.cc
@@ -0,0 +1,345 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <stack>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/message.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/map-util.h>
+
+namespace google {
+namespace protobuf {
+
+using internal::WireFormat;
+using internal::ReflectionOps;
+
+static string InitializationErrorMessage(const char* action,
+                                         const Message& message) {
+  return strings::Substitute(
+    "Can't $0 message of type \"$1\" because it is missing required "
+    "fields: $2",
+    action, message.GetDescriptor()->full_name(),
+    message.InitializationErrorString());
+}
+
+Message::~Message() {}
+Message::Reflection::~Reflection() {}
+
+void Message::MergeFrom(const Message& from) {
+  const Descriptor* descriptor = GetDescriptor();
+  GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
+    << ": 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());
+}
+
+void Message::CopyFrom(const Message& from) {
+  const Descriptor* descriptor = GetDescriptor();
+  GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
+    << ": 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());
+}
+
+void Message::Clear() {
+  ReflectionOps::Clear(GetDescriptor(), GetReflection());
+}
+
+bool Message::IsInitialized() const {
+  return ReflectionOps::IsInitialized(GetDescriptor(), *GetReflection());
+}
+
+void Message::FindInitializationErrors(vector<string>* errors) const {
+  return ReflectionOps::FindInitializationErrors(
+    GetDescriptor(), *GetReflection(), "", errors);
+}
+
+string Message::InitializationErrorString() const {
+  vector<string> errors;
+  FindInitializationErrors(&errors);
+  return JoinStrings(errors, ", ");
+}
+
+void Message::CheckInitialized() const {
+  GOOGLE_CHECK(IsInitialized())
+    << "Message of type \"" << GetDescriptor()->full_name()
+    << "\" is missing required fields: " << InitializationErrorString();
+}
+
+void Message::DiscardUnknownFields() {
+  return ReflectionOps::DiscardUnknownFields(GetDescriptor(), GetReflection());
+}
+
+bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) {
+  return WireFormat::ParseAndMergePartial(
+    GetDescriptor(), input, GetReflection());
+}
+
+bool Message::MergeFromCodedStream(io::CodedInputStream* input) {
+  if (!MergePartialFromCodedStream(input)) return false;
+  if (!IsInitialized()) {
+    GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *this);
+    return false;
+  }
+  return true;
+}
+
+bool Message::ParseFromCodedStream(io::CodedInputStream* input) {
+  Clear();
+  return MergeFromCodedStream(input);
+}
+
+bool Message::ParsePartialFromCodedStream(io::CodedInputStream* input) {
+  Clear();
+  return MergePartialFromCodedStream(input);
+}
+
+bool Message::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
+  io::CodedInputStream decoder(input);
+  return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage();
+}
+
+bool Message::ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input) {
+  io::CodedInputStream decoder(input);
+  return ParsePartialFromCodedStream(&decoder) &&
+         decoder.ConsumedEntireMessage();
+}
+
+bool Message::ParseFromString(const string& data) {
+  io::ArrayInputStream input(data.data(), data.size());
+  return ParseFromZeroCopyStream(&input);
+}
+
+bool Message::ParsePartialFromString(const string& data) {
+  io::ArrayInputStream input(data.data(), data.size());
+  return ParsePartialFromZeroCopyStream(&input);
+}
+
+bool Message::ParseFromArray(const void* data, int size) {
+  io::ArrayInputStream input(data, size);
+  return ParseFromZeroCopyStream(&input);
+}
+
+bool Message::ParsePartialFromArray(const void* data, int size) {
+  io::ArrayInputStream input(data, size);
+  return ParsePartialFromZeroCopyStream(&input);
+}
+
+bool Message::ParseFromFileDescriptor(int file_descriptor) {
+  io::FileInputStream input(file_descriptor);
+  return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0;
+}
+
+bool Message::ParsePartialFromFileDescriptor(int file_descriptor) {
+  io::FileInputStream input(file_descriptor);
+  return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0;
+}
+
+bool Message::ParseFromIstream(istream* input) {
+  io::IstreamInputStream zero_copy_input(input);
+  return ParseFromZeroCopyStream(&zero_copy_input) && input->eof();
+}
+
+bool Message::ParsePartialFromIstream(istream* input) {
+  io::IstreamInputStream zero_copy_input(input);
+  return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof();
+}
+
+
+
+bool Message::SerializeWithCachedSizes(
+    io::CodedOutputStream* output) const {
+  return WireFormat::SerializeWithCachedSizes(
+    GetDescriptor(), GetReflection(), GetCachedSize(), output);
+}
+
+int Message::ByteSize() const {
+  int size = WireFormat::ByteSize(GetDescriptor(), GetReflection());
+  SetCachedSize(size);
+  return size;
+}
+
+void Message::SetCachedSize(int size) const {
+  GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name()
+             << "\" implements neither SetCachedSize() nor ByteSize().  "
+                "Must implement one or the other.";
+}
+
+bool Message::SerializeToCodedStream(io::CodedOutputStream* output) const {
+  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
+  return SerializePartialToCodedStream(output);
+}
+
+bool Message::SerializePartialToCodedStream(
+    io::CodedOutputStream* output) const {
+  ByteSize();  // Force size to be cached.
+  if (!SerializeWithCachedSizes(output)) return false;
+  return true;
+}
+
+bool Message::SerializeToZeroCopyStream(
+    io::ZeroCopyOutputStream* output) const {
+  io::CodedOutputStream encoder(output);
+  return SerializeToCodedStream(&encoder);
+}
+
+bool Message::SerializePartialToZeroCopyStream(
+    io::ZeroCopyOutputStream* output) const {
+  io::CodedOutputStream encoder(output);
+  return SerializePartialToCodedStream(&encoder);
+}
+
+bool Message::AppendToString(string* output) const {
+  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
+  return AppendPartialToString(output);
+}
+
+bool Message::AppendPartialToString(string* output) const {
+  // For efficiency, we'd like to reserve the exact amount of space we need
+  // in the string.
+  int total_size = output->size() + ByteSize();
+  output->reserve(total_size);
+
+  io::StringOutputStream output_stream(output);
+
+  {
+    io::CodedOutputStream encoder(&output_stream);
+    if (!SerializeWithCachedSizes(&encoder)) return false;
+  }
+
+  GOOGLE_CHECK_EQ(output_stream.ByteCount(), total_size);
+  return true;
+}
+
+bool Message::SerializeToString(string* output) const {
+  output->clear();
+  return AppendToString(output);
+}
+
+bool Message::SerializePartialToString(string* output) const {
+  output->clear();
+  return AppendPartialToString(output);
+}
+
+bool Message::SerializeToArray(void* data, int size) const {
+  io::ArrayOutputStream output_stream(data, size);
+  return SerializeToZeroCopyStream(&output_stream);
+}
+
+bool Message::SerializePartialToArray(void* data, int size) const {
+  io::ArrayOutputStream output_stream(data, size);
+  return SerializePartialToZeroCopyStream(&output_stream);
+}
+
+bool Message::SerializeToFileDescriptor(int file_descriptor) const {
+  io::FileOutputStream output(file_descriptor);
+  return SerializeToZeroCopyStream(&output);
+}
+
+bool Message::SerializePartialToFileDescriptor(int file_descriptor) const {
+  io::FileOutputStream output(file_descriptor);
+  return SerializePartialToZeroCopyStream(&output);
+}
+
+bool Message::SerializeToOstream(ostream* output) const {
+  io::OstreamOutputStream zero_copy_output(output);
+  return SerializeToZeroCopyStream(&zero_copy_output);
+}
+
+bool Message::SerializePartialToOstream(ostream* output) const {
+  io::OstreamOutputStream zero_copy_output(output);
+  return SerializePartialToZeroCopyStream(&zero_copy_output);
+}
+
+
+// ===================================================================
+// MessageFactory
+
+MessageFactory::~MessageFactory() {}
+
+namespace {
+
+class GeneratedMessageFactory : public MessageFactory {
+ public:
+  GeneratedMessageFactory();
+  ~GeneratedMessageFactory();
+
+  static GeneratedMessageFactory* singleton();
+
+  void RegisterType(const Descriptor* descriptor, const Message* prototype);
+
+  // implements MessageFactory ---------------------------------------
+  const Message* GetPrototype(const Descriptor* type);
+
+ private:
+  hash_map<const Descriptor*, const Message*> type_map_;
+};
+
+GeneratedMessageFactory::GeneratedMessageFactory() {}
+GeneratedMessageFactory::~GeneratedMessageFactory() {}
+
+GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
+  // No need for thread-safety here because this will be called at static
+  // initialization time.  (And GCC4 makes this thread-safe anyway.)
+  static GeneratedMessageFactory singleton;
+  return &singleton;
+}
+
+void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor,
+                                           const Message* prototype) {
+  GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool())
+    << "Tried to register a non-generated type with the generated "
+       "type registry.";
+
+  if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) {
+    GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name();
+  }
+}
+
+const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
+  return FindPtrOrNull(type_map_, type);
+}
+
+}  // namespace
+
+MessageFactory* MessageFactory::generated_factory() {
+  return GeneratedMessageFactory::singleton();
+}
+
+void MessageFactory::InternalRegisterGeneratedMessage(
+    const Descriptor* descriptor, const Message* prototype) {
+  GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype);
+}
+
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
new file mode 100644
index 0000000..2c2cf5b
--- /dev/null
+++ b/src/google/protobuf/message.h
@@ -0,0 +1,624 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains the abstract interface for all protocol messages.
+// Although it's possible to implement this interface manually, most users
+// will use the protocol compiler to generate implementations.
+//
+// Example usage:
+//
+// Say you have a message defined as:
+//
+//   message Foo {
+//     optional string text = 1;
+//     repeated int32 numbers = 2;
+//   }
+//
+// Then, if you used the protocol compiler to generate a class from the above
+// definition, you could use it like so:
+//
+//   string data;  // Will store a serialized version of the message.
+//
+//   {
+//     // Create a message and serialize it.
+//     Foo foo;
+//     foo.set_text("Hello World!");
+//     foo.add_numbers(1);
+//     foo.add_numbers(5);
+//     foo.add_numbers(42);
+//
+//     foo.SerializeToString(&data);
+//   }
+//
+//   {
+//     // Parse the serialized message and check that it contains the
+//     // correct data.
+//     Foo foo;
+//     foo.ParseFromString(data);
+//
+//     assert(foo.text() == "Hello World!");
+//     assert(foo.numbers_size() == 3);
+//     assert(foo.numbers(0) == 1);
+//     assert(foo.numbers(1) == 5);
+//     assert(foo.numbers(2) == 42);
+//   }
+//
+//   {
+//     // Same as the last block, but do it dynamically via the Message
+//     // reflection interface.
+//     Message* foo = new Foo;
+//     Descriptor* descriptor = foo->GetDescriptor();
+//
+//     // Get the descriptors for the fields we're interested in and verify
+//     // their types.
+//     FieldDescriptor* text_field = descriptor->FindFieldByName("text");
+//     assert(text_field != NULL);
+//     assert(text_field->type() == FieldDescriptor::TYPE_STRING);
+//     assert(text_field->label() == FieldDescriptor::TYPE_OPTIONAL);
+//     FieldDescriptor* numbers_field = descriptor->FindFieldByName("numbers");
+//     assert(numbers_field != NULL);
+//     assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
+//     assert(numbers_field->label() == FieldDescriptor::TYPE_REPEATED);
+//
+//     // Parse the message.
+//     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);
+//
+//     delete foo;
+//   }
+
+#ifndef GOOGLE_PROTOBUF_MESSAGE_H__
+#define GOOGLE_PROTOBUF_MESSAGE_H__
+
+#include <vector>
+#include <string>
+#include <iosfwd>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+
+namespace protobuf {
+
+// Defined in this file.
+class Message;
+
+// Defined in other files.
+class Descriptor;            // descriptor.h
+class FieldDescriptor;       // descriptor.h
+class EnumValueDescriptor;   // descriptor.h
+namespace io {
+  class ZeroCopyInputStream;   // zero_copy_stream.h
+  class ZeroCopyOutputStream;  // zero_copy_stream.h
+  class CodedInputStream;      // coded_stream.h
+  class CodedOutputStream;     // coded_stream.h
+}
+class UnknownFieldSet;       // unknown_field_set.h
+
+// Abstract interface for protocol messages.
+//
+// The methods of this class that are virtual but not pure-virtual have
+// default implementations based on reflection.  Message classes which are
+// optimized for speed will want to override these with faster implementations,
+// but classes optimized for code size may be happy with keeping them.  See
+// the optimize_for option in descriptor.proto.
+class LIBPROTOBUF_EXPORT Message {
+ public:
+  inline Message() {}
+  virtual ~Message();
+
+  // Basic Operations ------------------------------------------------
+
+  // Construct a new instance of the same type.  Ownership is passed to the
+  // caller.
+  virtual Message* New() const = 0;
+
+  // Make this message into a copy of the given message.  The given message
+  // must have the same descriptor, but need not necessarily be the same class.
+  // By default this is just implemented as "Clear(); MergeFrom(from);".
+  virtual void CopyFrom(const Message& from);
+
+  // Merge the fields from the given message into this message.  Singular
+  // fields will be overwritten, except for embedded messages which will
+  // be merged.  Repeated fields will be concatenated.  The given message
+  // must be of the same type as this message (i.e. the exact same class).
+  virtual void MergeFrom(const Message& from);
+
+  // Clear all fields of the message and set them to their default values.
+  // Clear() avoids freeing memory, assuming that any memory allocated
+  // to hold parts of the message will be needed again to hold the next
+  // message.  If you actually want to free the memory used by a Message,
+  // you must delete it.
+  virtual void Clear();
+
+  // Quickly check if all required fields have values set.
+  virtual bool IsInitialized() const;
+
+  // Verifies that IsInitialized() returns true.  GOOGLE_CHECK-fails otherwise, with
+  // a nice error message.
+  void CheckInitialized() const;
+
+  // Slowly build a list of all required fields that are not set.
+  // This is much, much slower than IsInitialized() as it is implemented
+  // purely via reflection.  Generally, you should not call this unless you
+  // have already determined that an error exists by calling IsInitialized().
+  void FindInitializationErrors(vector<string>* errors) const;
+
+  // Like FindInitializationErrors, but joins all the strings, delimited by
+  // commas, and returns them.
+  string InitializationErrorString() const;
+
+  // Clears all unknown fields from this message and all embedded messages.
+  // Normally, if unknown tag numbers are encountered when parsing a message,
+  // the tag and value are stored in the message's UnknownFieldSet and
+  // then written back out when the message is serialized.  This allows servers
+  // which simply route messages to other servers to pass through messages
+  // that have new field definitions which they don't yet know about.  However,
+  // this behavior can have security implications.  To avoid it, call this
+  // method after parsing.
+  //
+  // See Reflection::GetUnknownFields() for more on unknown fields.
+  virtual void DiscardUnknownFields();
+
+  // Debugging -------------------------------------------------------
+
+  // Generates a human readable form of this message, useful for debugging
+  // and other purposes.
+  string DebugString() const;
+  // Like DebugString(), but with less whitespace.
+  string ShortDebugString() const;
+  // Convenience function useful in GDB.  Prints DebugString() to stdout.
+  void PrintDebugString() const;
+
+  // Parsing ---------------------------------------------------------
+  // Methods for parsing in protocol buffer format.  Most of these are
+  // just simple wrappers around MergeFromCodedStream().
+
+  // Fill the message with a protocol buffer parsed from the given input
+  // stream.  Returns false on a read error or if the input is in the
+  // wrong format.
+  bool ParseFromCodedStream(io::CodedInputStream* input);
+  // Like ParseFromCodedStream(), but accepts messages that are missing
+  // required fields.
+  bool ParsePartialFromCodedStream(io::CodedInputStream* input);
+  // Read a protocol buffer from the given zero-copy input stream.  If
+  // successful, the entire input will be consumed.
+  bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
+  // Like ParseFromZeroCopyStream(), but accepts messages that are missing
+  // required fields.
+  bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input);
+  // Parse a protocol buffer contained in a string.
+  bool ParseFromString(const string& data);
+  // Like ParseFromString(), but accepts messages that are missing
+  // required fields.
+  bool ParsePartialFromString(const string& data);
+  // Parse a protocol buffer contained in an array of bytes.
+  bool ParseFromArray(const void* data, int size);
+  // Like ParseFromArray(), but accepts messages that are missing
+  // required fields.
+  bool ParsePartialFromArray(const void* data, int size);
+
+  // Parse a protocol buffer from a file descriptor.  If successful, the entire
+  // input will be consumed.
+  bool ParseFromFileDescriptor(int file_descriptor);
+  // Like ParseFromFileDescriptor(), but accepts messages that are missing
+  // required fields.
+  bool ParsePartialFromFileDescriptor(int file_descriptor);
+  // Parse a protocol buffer from a C++ istream.  If successful, the entire
+  // input will be consumed.
+  bool ParseFromIstream(istream* input);
+  // Like ParseFromIstream(), but accepts messages that are missing
+  // required fields.
+  bool ParsePartialFromIstream(istream* input);
+
+
+  // Reads a protocol buffer from the stream and merges it into this
+  // Message.  Singular fields read from the input overwrite what is
+  // already in the Message and repeated fields are appended to those
+  // already present.
+  //
+  // It is the responsibility of the caller to call input->LastTagWas()
+  // (for groups) or input->ConsumedEntireMessage() (for non-groups) after
+  // this returns to verify that the message's end was delimited correctly.
+  //
+  // ParsefromCodedStream() is implemented as Clear() followed by
+  // MergeFromCodedStream().
+  bool MergeFromCodedStream(io::CodedInputStream* input);
+
+  // Like MergeFromCodedStream(), but succeeds even if required fields are
+  // missing in the input.
+  //
+  // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream()
+  // followed by IsInitialized().
+  virtual bool MergePartialFromCodedStream(io::CodedInputStream* input);
+
+  // Serialization ---------------------------------------------------
+  // Methods for serializing in protocol buffer format.  Most of these
+  // are just simple wrappers around ByteSize() and SerializeWithCachedSizes().
+
+  // Write a protocol buffer of this message to the given output.  Returns
+  // false on a write error.  If the message is missing required fields,
+  // this may GOOGLE_CHECK-fail.
+  bool SerializeToCodedStream(io::CodedOutputStream* output) const;
+  // Like SerializeToCodedStream(), but allows missing required fields.
+  bool SerializePartialToCodedStream(io::CodedOutputStream* output) const;
+  // Write the message to the given zero-copy output stream.  All required
+  // fields must be set.
+  bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const;
+  // Like SerializeToZeroCopyStream(), but allows missing required fields.
+  bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const;
+  // Serialize the message and store it in the given string.  All required
+  // fields must be set.
+  bool SerializeToString(string* output) const;
+  // Like SerializeToString(), but allows missing required fields.
+  bool SerializePartialToString(string* output) const;
+  // Serialize the message and store it in the given byte array.  All required
+  // fields must be set.
+  bool SerializeToArray(void* data, int size) const;
+  // Like SerializeToArray(), but allows missing required fields.
+  bool SerializePartialToArray(void* data, int size) const;
+
+  // Serialize the message and write it to the given file descriptor.  All
+  // required fields must be set.
+  bool SerializeToFileDescriptor(int file_descriptor) const;
+  // Like SerializeToFileDescriptor(), but allows missing required fields.
+  bool SerializePartialToFileDescriptor(int file_descriptor) const;
+  // Serialize the message and write it to the given C++ ostream.  All
+  // required fields must be set.
+  bool SerializeToOstream(ostream* output) const;
+  // Like SerializeToOstream(), but allows missing required fields.
+  bool SerializePartialToOstream(ostream* output) const;
+
+
+  // Like SerializeToString(), but appends to the data to the string's existing
+  // contents.  All required fields must be set.
+  bool AppendToString(string* output) const;
+  // Like AppendToString(), but allows missing required fields.
+  bool AppendPartialToString(string* output) const;
+
+  // Computes the serialized size of the message.  This recursively calls
+  // ByteSize() on all embedded messages.  If a subclass does not override
+  // this, it MUST override SetCachedSize().
+  virtual int ByteSize() const;
+
+  // Serializes the message without recomputing the size.  The message must
+  // not have changed since the last call to ByteSize(); if it has, the results
+  // are undefined.
+  virtual bool SerializeWithCachedSizes(io::CodedOutputStream* output) const;
+
+  // Returns the result of the last call to ByteSize().  An embedded message's
+  // size is needed both to serialize it (because embedded messages are
+  // length-delimited) and to compute the outer message's size.  Caching
+  // the size avoids computing it multiple times.
+  //
+  // ByteSize() does not automatically use the cached size when available
+  // because this would require invalidating it every time the message was
+  // modified, which would be too hard and expensive.  (E.g. if a deeply-nested
+  // sub-message is changed, all of its parents' cached sizes would need to be
+  // invalidated, which is too much work for an otherwise inlined setter
+  // method.)
+  virtual int GetCachedSize() const = 0;
+
+ private:
+  // This is called only by the default implementation of ByteSize(), to
+  // update the cached size.  If you override ByteSize(), you do not need
+  // to override this.  If you do not override ByteSize(), you MUST override
+  // this; the default implementation will crash.
+  //
+  // The method is private because subclasses should never call it; only
+  // override it.  Yes, C++ lets you do that.  Crazy, huh?
+  virtual void SetCachedSize(int size) const;
+
+ public:
+
+  // Introspection ---------------------------------------------------
+
+  class Reflection;  // Defined below.
+
+  // Get a Descriptor for this message's type.  This describes what
+  // fields the message contains, the types of those fields, etc.
+  virtual const Descriptor* GetDescriptor() 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 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);
+};
+
+// This interface contains methods that can be used to dynamically access
+// and modify the fields of a protocol message.  Their semantics are
+// similar to the accessors the protocol compiler generates.
+//
+// To get the Reflection for a given Message, call Message::GetReflection().
+//
+// 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).
+//
+// There are several ways that these methods can be used incorrectly.  For
+// example, any of the following conditions will lead to undefined
+// results (probably assertion failures):
+// - The FieldDescriptor is not a field of this message type.
+// - The method called is not appropriate for the field's type.  For
+//   each field type in FieldDescriptor::TYPE_*, there is only one
+//   Get*() method, one Set*() method, and one Add*() method that is
+//   valid for that type.  It should be obvious which (except maybe
+//   for TYPE_BYTES, which are represented using strings in C++).
+// - A Get*() or Set*() method for singular fields is called on a repeated
+//   field.
+// - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated
+//   field.
+//
+// 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
+// returns "const Field&", where "Field" is some class with accessors like
+// "GetInt32Value()".  The problem is that someone would have to deal with
+// allocating these Field objects.  For generated message classes, having to
+// allocate space for an additional object to wrap every field would at least
+// double the message's memory footprint, probably worse.  Allocating the
+// objects on-demand, on the other hand, would be expensive and prone to
+// memory leaks.  So, instead we ended up with this flat interface.
+//
+// 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 {
+ public:
+  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;
+  // 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;
+
+  // Check if the given non-repeated field is set.
+  virtual bool HasField(const FieldDescriptor* field) const = 0;
+
+  // Get the number of elements of a repeated field.
+  virtual int FieldSize(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;
+
+  // 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;
+
+  // 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 const EnumValueDescriptor* GetEnum(
+      const FieldDescriptor* field) const = 0;
+  virtual const Message& GetMessage(const FieldDescriptor* field) const = 0;
+
+  // Get a string value without copying, if possible.
+  //
+  // GetString() necessarily returns a copy of the string.  This can be
+  // inefficient when the string is already stored in a string object in the
+  // underlying message.  GetStringReference() will return a reference to the
+  // underlying string in this case.  Otherwise, it will copy the string into
+  // *scratch and return that.
+  //
+  // Note:  It is perfectly reasonable and useful to write code like:
+  //     str = reflection->GetStringReference(field, &str);
+  //   This line would ensure that only one copy of the string is made
+  //   regardless of the field's underlying representation.  When initializing
+  //   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,
+                                           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;
+  // Get a mutable pointer to a field with a message type.
+  virtual Message* MutableMessage(const FieldDescriptor* field) = 0;
+
+
+  // Repeated field getters ------------------------------------------
+  // These get the value of one element of a repeated field.
+
+  virtual int32  GetRepeatedInt32 (const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual int64  GetRepeatedInt64 (const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual uint32 GetRepeatedUInt32(const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual uint64 GetRepeatedUInt64(const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual float  GetRepeatedFloat (const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual double GetRepeatedDouble(const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual bool   GetRepeatedBool  (const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual string GetRepeatedString(const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual const EnumValueDescriptor* GetRepeatedEnum(
+      const FieldDescriptor* field, int index) const = 0;
+  virtual const Message& GetRepeatedMessage(
+      const FieldDescriptor* field, int index) const = 0;
+
+  // See GetStringReference(), above.
+  virtual const string& GetRepeatedStringReference(
+      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;
+  // Get a mutable pointer to an element of a repeated field with a message
+  // type.
+  virtual Message* MutableRepeatedMessage(
+      const FieldDescriptor* field, int index) = 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;
+
+
+  // Extensions ------------------------------------------------------
+
+  // Try to find an extension of this message type by fully-qualified field
+  // name.  Returns NULL if no extension is known for this name or number.
+  virtual const FieldDescriptor* FindKnownExtensionByName(
+      const string& name) const = 0;
+
+  // Try to find an extension of this message type by field number.
+  // Returns NULL if no extension is known for this name or number.
+  virtual const FieldDescriptor* FindKnownExtensionByNumber(
+      int number) const = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
+};
+
+// Abstract interface for a factory for message objects.
+class LIBPROTOBUF_EXPORT MessageFactory {
+ public:
+  inline MessageFactory() {}
+  virtual ~MessageFactory();
+
+  // Given a Descriptor, gets or constructs the default (prototype) Message
+  // of that type.  You can then call that message's New() method to construct
+  // a mutable message of that type.
+  //
+  // Calling this method twice with the same Descriptor returns the same
+  // object.  The returned object remains property of the factory.  Also, any
+  // objects created by calling the prototype's New() method share some data
+  // with the prototype, so these must be destoyed before the MessageFactory
+  // is destroyed.
+  //
+  // The given descriptor must outlive the returned message, and hence must
+  // outlive the MessageFactory.
+  //
+  // Some implementations do not support all types.  GetPrototype() will
+  // return NULL if the descriptor passed in is not supported.
+  //
+  // This method may or may not be thread-safe depending on the implementation.
+  // Each implementation should document its own degree thread-safety.
+  virtual const Message* GetPrototype(const Descriptor* type) = 0;
+
+  // Gets a MessageFactory which supports all generated, compiled-in messages.
+  // In other words, for any compiled-in type FooMessage, the following is true:
+  //   MessageFactory::generated_factory()->GetPrototype(
+  //     FooMessage::descriptor()) == FooMessage::default_instance()
+  // This factory supports all types which are found in
+  // DescriptorPool::generated_pool().  If given a descriptor from any other
+  // pool, GetPrototype() will return NULL.  (You can also check if a
+  // descriptor is for a generated message by checking if
+  // descriptor->file()->pool() == DescriptorPool::generated_pool().)
+  //
+  // This factory is 100% thread-safe; calling GetPrototype() does not modify
+  // any shared data.
+  //
+  // This factory is a singleton.  The caller must not delete the object.
+  static MessageFactory* generated_factory();
+
+  // For internal use only:  Registers a message type at static initialization
+  // time, to be placed in generated_factory().
+  static void InternalRegisterGeneratedMessage(const Descriptor* descriptor,
+                                               const Message* prototype);
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_MESSAGE_H__
diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc
new file mode 100644
index 0000000..491d379
--- /dev/null
+++ b/src/google/protobuf/message_unittest.cc
@@ -0,0 +1,224 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/message.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include <sstream>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0     // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+TEST(MessageTest, SerializeHelpers) {
+  // TODO(kenton):  Test more helpers?  They're all two-liners so it seems
+  //   like a waste of time.
+
+  protobuf_unittest::TestAllTypes message;
+  TestUtil::SetAllFields(&message);
+  stringstream stream;
+
+  string str1("foo");
+  string str2("bar");
+
+  message.SerializeToString(&str1);
+  message.AppendToString(&str2);
+  message.SerializeToOstream(&stream);
+
+  EXPECT_EQ(str1.size() + 3, str2.size());
+  EXPECT_EQ("bar", str2.substr(0, 3));
+  // Don't use EXPECT_EQ because we don't want to dump raw binary data to
+  // stdout.
+  EXPECT_TRUE(str2.substr(3) == str1);
+
+  // GCC gives some sort of error if we try to just do stream.str() == str1.
+  string temp = stream.str();
+  EXPECT_TRUE(temp == str1);
+
+}
+
+TEST(MessageTest, ParseFromFileDescriptor) {
+  string filename = TestSourceDir() +
+                    "/google/protobuf/testdata/golden_message";
+  int file = open(filename.c_str(), O_RDONLY | O_BINARY);
+
+  unittest::TestAllTypes message;
+  EXPECT_TRUE(message.ParseFromFileDescriptor(file));
+  TestUtil::ExpectAllFieldsSet(message);
+
+  EXPECT_GE(close(file), 0);
+}
+
+TEST(MessageTest, ParseHelpers) {
+  // TODO(kenton):  Test more helpers?  They're all two-liners so it seems
+  //   like a waste of time.
+  string data;
+
+  {
+    // Set up.
+    protobuf_unittest::TestAllTypes message;
+    TestUtil::SetAllFields(&message);
+    message.SerializeToString(&data);
+  }
+
+  {
+    // Test ParseFromString.
+    protobuf_unittest::TestAllTypes message;
+    EXPECT_TRUE(message.ParseFromString(data));
+    TestUtil::ExpectAllFieldsSet(message);
+  }
+
+  {
+    // Test ParseFromIstream.
+    protobuf_unittest::TestAllTypes message;
+    stringstream stream(data);
+    EXPECT_TRUE(message.ParseFromIstream(&stream));
+    EXPECT_TRUE(stream.eof());
+    TestUtil::ExpectAllFieldsSet(message);
+  }
+}
+
+TEST(MessageTest, ParseFailsIfNotInitialized) {
+  unittest::TestRequired message;
+  vector<string> errors;
+
+  {
+    ScopedMemoryLog log;
+    EXPECT_FALSE(message.ParseFromString(""));
+    errors = log.GetMessages(ERROR);
+  }
+
+  ASSERT_EQ(1, errors.size());
+  EXPECT_EQ("Can't parse message of type \"protobuf_unittest.TestRequired\" "
+            "because it is missing required fields: a, b, c",
+            errors[0]);
+}
+
+TEST(MessageTest, BypassInitializationCheckOnParse) {
+  unittest::TestRequired message;
+  io::ArrayInputStream raw_input(NULL, 0);
+  io::CodedInputStream input(&raw_input);
+  EXPECT_TRUE(message.MergePartialFromCodedStream(&input));
+}
+
+TEST(MessageTest, InitializationErrorString) {
+  unittest::TestRequired message;
+  EXPECT_EQ("a, b, c", message.InitializationErrorString());
+}
+
+#ifdef GTEST_HAS_DEATH_TEST  // death tests do not work on Windows yet.
+
+TEST(MessageTest, SerializeFailsIfNotInitialized) {
+  unittest::TestRequired message;
+  string data;
+  EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)),
+    "Can't serialize message of type \"protobuf_unittest.TestRequired\" because "
+    "it is missing required fields: a, b, c");
+}
+
+TEST(MessageTest, CheckInitialized) {
+  unittest::TestRequired message;
+  EXPECT_DEATH(message.CheckInitialized(),
+    "Message of type \"protobuf_unittest.TestRequired\" is missing required "
+    "fields: a, b, c");
+}
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+TEST(MessageTest, BypassInitializationCheckOnSerialize) {
+  unittest::TestRequired message;
+  io::ArrayOutputStream raw_output(NULL, 0);
+  io::CodedOutputStream output(&raw_output);
+  EXPECT_TRUE(message.SerializePartialToCodedStream(&output));
+}
+
+TEST(MessageTest, FindInitializationErrors) {
+  unittest::TestRequired message;
+  vector<string> errors;
+  message.FindInitializationErrors(&errors);
+  ASSERT_EQ(3, errors.size());
+  EXPECT_EQ("a", errors[0]);
+  EXPECT_EQ("b", errors[1]);
+  EXPECT_EQ("c", errors[2]);
+}
+
+TEST(MessageTest, ParseFailsOnInvalidMessageEnd) {
+  unittest::TestAllTypes message;
+
+  // Control case.
+  EXPECT_TRUE(message.ParseFromArray("", 0));
+
+  // The byte is a valid varint, but not a valid tag (zero).
+  EXPECT_FALSE(message.ParseFromArray("\0", 1));
+
+  // The byte is a malformed varint.
+  EXPECT_FALSE(message.ParseFromArray("\200", 1));
+
+  // The byte is an endgroup tag, but we aren't parsing a group.
+  EXPECT_FALSE(message.ParseFromArray("\014", 1));
+}
+
+TEST(MessageFactoryTest, GeneratedFactoryLookup) {
+  EXPECT_EQ(
+    MessageFactory::generated_factory()->GetPrototype(
+      protobuf_unittest::TestAllTypes::descriptor()),
+    &protobuf_unittest::TestAllTypes::default_instance());
+}
+
+TEST(MessageFactoryTest, GeneratedFactoryUnknownType) {
+  // Construct a new descriptor.
+  DescriptorPool pool;
+  FileDescriptorProto file;
+  file.set_name("foo.proto");
+  file.add_message_type()->set_name("Foo");
+  const Descriptor* descriptor = pool.BuildFile(file)->message_type(0);
+
+  // Trying to construct it should return NULL.
+  EXPECT_TRUE(
+    MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL);
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/package_info.h b/src/google/protobuf/package_info.h
new file mode 100644
index 0000000..0ba6e79
--- /dev/null
+++ b/src/google/protobuf/package_info.h
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file exists solely to document the google::protobuf namespace.
+// It is not compiled into anything, but it may be read by an automated
+// documentation generator.
+
+namespace google {
+
+// Core components of the Protocol Buffers runtime library.
+//
+// The files in this package represent the core of the Protocol Buffer
+// system.  All of them are part of the libprotobuf library.
+//
+// A note on thread-safety:
+//
+// Thread-safety in the Protocol Buffer library follows a simple rule:
+// unless explicitly noted otherwise, it is always safe to use an object
+// from multiple threads simultaneously as long as the object is declared
+// const in all threads (or, it is only used in ways that would be allowed
+// if it were declared const).  However, if an object is accessed in one
+// thread in a way that would not be allowed if it were const, then it is
+// not safe to access that object in any other thread simultaneously.
+//
+// Put simply, read-only access to an object can happen in multiple threads
+// simultaneously, but write access can only happen in a single thread at
+// a time.
+//
+// The implementation does contain some "const" methods which actually modify
+// the object behind the scenes -- e.g., to cache results -- but in these cases
+// mutex locking is used to make the access thread-safe.
+namespace protobuf {}
+}  // namespace google
diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc
new file mode 100644
index 0000000..2b26329
--- /dev/null
+++ b/src/google/protobuf/reflection_ops.cc
@@ -0,0 +1,241 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+void ReflectionOps::Copy(const Descriptor* descriptor,
+                         const Message::Reflection& from,
+                         Message::Reflection* to) {
+  if (&from == to) return;
+  Clear(descriptor, to);
+  Merge(descriptor, from, to);
+}
+
+void ReflectionOps::Merge(const Descriptor* descriptor,
+                          const Message::Reflection& from,
+                          Message::Reflection* to) {
+  GOOGLE_CHECK_NE(&from, to);
+  vector<const FieldDescriptor*> fields;
+  from.ListFields(&fields);
+  for (int i = 0; i < fields.size(); i++) {
+    const FieldDescriptor* field = fields[i];
+
+    if (field->is_repeated()) {
+      int count = from.FieldSize(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));                       \
+            break;
+
+          HANDLE_TYPE(INT32 , Int32 );
+          HANDLE_TYPE(INT64 , Int64 );
+          HANDLE_TYPE(UINT32, UInt32);
+          HANDLE_TYPE(UINT64, UInt64);
+          HANDLE_TYPE(FLOAT , Float );
+          HANDLE_TYPE(DOUBLE, Double);
+          HANDLE_TYPE(BOOL  , Bool  );
+          HANDLE_TYPE(STRING, String);
+          HANDLE_TYPE(ENUM  , Enum  );
+#undef HANDLE_TYPE
+
+          case FieldDescriptor::CPPTYPE_MESSAGE:
+            to->AddMessage(field)->MergeFrom(
+              from.GetRepeatedMessage(field, j));
+            break;
+        }
+      }
+    } else if (from.HasField(field)) {
+      switch (field->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, METHOD)                                        \
+        case FieldDescriptor::CPPTYPE_##CPPTYPE:                            \
+          to->Set##METHOD(field, from.Get##METHOD(field));                  \
+          break;
+
+        HANDLE_TYPE(INT32 , Int32 );
+        HANDLE_TYPE(INT64 , Int64 );
+        HANDLE_TYPE(UINT32, UInt32);
+        HANDLE_TYPE(UINT64, UInt64);
+        HANDLE_TYPE(FLOAT , Float );
+        HANDLE_TYPE(DOUBLE, Double);
+        HANDLE_TYPE(BOOL  , Bool  );
+        HANDLE_TYPE(STRING, String);
+        HANDLE_TYPE(ENUM  , Enum  );
+#undef HANDLE_TYPE
+
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          to->MutableMessage(field)->MergeFrom(
+            from.GetMessage(field));
+          break;
+      }
+    }
+  }
+
+  to->MutableUnknownFields()->MergeFrom(from.GetUnknownFields());
+}
+
+void ReflectionOps::Clear(const Descriptor* descriptor,
+                          Message::Reflection* reflection) {
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(&fields);
+  for (int i = 0; i < fields.size(); i++) {
+    reflection->ClearField(fields[i]);
+  }
+
+  reflection->MutableUnknownFields()->Clear();
+}
+
+bool ReflectionOps::IsInitialized(const Descriptor* descriptor,
+                                  const Message::Reflection& reflection) {
+  // 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))) {
+        return false;
+      }
+    }
+  }
+
+  // Check that sub-messages are initialized.
+  vector<const FieldDescriptor*> fields;
+  reflection.ListFields(&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);
+
+        for (int i = 0; i < size; i++) {
+          if (!reflection.GetRepeatedMessage(field, i).IsInitialized()) {
+            return false;
+          }
+        }
+      } else {
+        if (reflection.HasField(field) &&
+            !reflection.GetMessage(field).IsInitialized()) {
+          return false;
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+void ReflectionOps::DiscardUnknownFields(
+    const Descriptor* descriptor,
+    Message::Reflection* reflection) {
+  reflection->MutableUnknownFields()->Clear();
+
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(&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);
+        for (int i = 0; i < size; i++) {
+          reflection->MutableRepeatedMessage(field, i)->DiscardUnknownFields();
+        }
+      } else {
+        if (reflection->HasField(field)) {
+          reflection->MutableMessage(field)->DiscardUnknownFields();
+        }
+      }
+    }
+  }
+}
+
+static string SubMessagePrefix(const string& prefix,
+                               const FieldDescriptor* field,
+                               int index) {
+  string result(prefix);
+  if (field->is_extension()) {
+    result.append("(");
+    result.append(field->full_name());
+    result.append(")");
+  } else {
+    result.append(field->name());
+  }
+  if (index != -1) {
+    result.append("[");
+    result.append(SimpleItoa(index));
+    result.append("]");
+  }
+  result.append(".");
+  return result;
+}
+
+void ReflectionOps::FindInitializationErrors(
+    const Descriptor* descriptor,
+    const Message::Reflection& reflection,
+    const string& prefix,
+    vector<string>* errors) {
+  // 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))) {
+        errors->push_back(prefix + descriptor->field(i)->name());
+      }
+    }
+  }
+
+  // Check sub-messages.
+  vector<const FieldDescriptor*> fields;
+  reflection.ListFields(&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);
+
+        for (int i = 0; i < size; i++) {
+          const Message& sub_message = reflection.GetRepeatedMessage(field, i);
+          FindInitializationErrors(field->message_type(),
+                                   *sub_message.GetReflection(),
+                                   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);
+        }
+      }
+    }
+  }
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/reflection_ops.h b/src/google/protobuf/reflection_ops.h
new file mode 100644
index 0000000..4a7f76b
--- /dev/null
+++ b/src/google/protobuf/reflection_ops.h
@@ -0,0 +1,74 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__
+#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__
+
+#include <google/protobuf/message.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Basic operations that can be performed using Message::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.
+//
+// This class should stay limited to operations needed to implement
+// the Message interface.
+//
+// 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);
+
+  // 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,
+                                       const string& prefix,
+                                       vector<string>* errors);
+
+ private:
+  // All methods are static.  No need to construct.
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionOps);
+};
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_REFLECTION_OPS_H__
diff --git a/src/google/protobuf/reflection_ops_unittest.cc b/src/google/protobuf/reflection_ops_unittest.cc
new file mode 100644
index 0000000..e1af2fc
--- /dev/null
+++ b/src/google/protobuf/reflection_ops_unittest.cc
@@ -0,0 +1,421 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(ReflectionOpsTest, SanityCheck) {
+  unittest::TestAllTypes message;
+
+  TestUtil::SetAllFields(&message);
+  TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(ReflectionOpsTest, Copy) {
+  unittest::TestAllTypes message, message2;
+
+  TestUtil::SetAllFields(&message);
+
+  ReflectionOps::Copy(message.descriptor(), *message.GetReflection(),
+                      message2.GetReflection());
+
+  TestUtil::ExpectAllFieldsSet(message2);
+
+  // Copying from self should be a no-op.
+  ReflectionOps::Copy(message2.descriptor(), *message2.GetReflection(),
+                      message2.GetReflection());
+  TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(ReflectionOpsTest, CopyExtensions) {
+  unittest::TestAllExtensions message, message2;
+
+  TestUtil::SetAllExtensions(&message);
+
+  ReflectionOps::Copy(message.descriptor(), *message.GetReflection(),
+                      message2.GetReflection());
+
+  TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ReflectionOpsTest, Merge) {
+  // Note:  Copy is implemented in terms of Merge() so technically the Copy
+  //   test already tested most of this.
+
+  unittest::TestAllTypes message, message2;
+
+  TestUtil::SetAllFields(&message);
+
+  // This field will test merging into an empty spot.
+  message2.set_optional_int32(message.optional_int32());
+  message.clear_optional_int32();
+
+  // This tests overwriting.
+  message2.set_optional_string(message.optional_string());
+  message.set_optional_string("something else");
+
+  // This tests concatenating.
+  message2.add_repeated_int32(message.repeated_int32(1));
+  int32 i = message.repeated_int32(0);
+  message.clear_repeated_int32();
+  message.add_repeated_int32(i);
+
+  ReflectionOps::Merge(message2.descriptor(), *message2.GetReflection(),
+                       message.GetReflection());
+
+  TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(ReflectionOpsTest, MergeExtensions) {
+  // Note:  Copy is implemented in terms of Merge() so technically the Copy
+  //   test already tested most of this.
+
+  unittest::TestAllExtensions message, message2;
+
+  TestUtil::SetAllExtensions(&message);
+
+  // This field will test merging into an empty spot.
+  message2.SetExtension(unittest::optional_int32_extension,
+    message.GetExtension(unittest::optional_int32_extension));
+  message.ClearExtension(unittest::optional_int32_extension);
+
+  // This tests overwriting.
+  message2.SetExtension(unittest::optional_string_extension,
+    message.GetExtension(unittest::optional_string_extension));
+  message.SetExtension(unittest::optional_string_extension, "something else");
+
+  // This tests concatenating.
+  message2.AddExtension(unittest::repeated_int32_extension,
+    message.GetExtension(unittest::repeated_int32_extension, 1));
+  int32 i = message.GetExtension(unittest::repeated_int32_extension, 0);
+  message.ClearExtension(unittest::repeated_int32_extension);
+  message.AddExtension(unittest::repeated_int32_extension, i);
+
+  ReflectionOps::Merge(message2.descriptor(), *message2.GetReflection(),
+                       message.GetReflection());
+
+  TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ReflectionOpsTest, MergeUnknown) {
+  // Test that the messages' UnknownFieldSets are correctly merged.
+  unittest::TestEmptyMessage message1, message2;
+  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());
+
+  ASSERT_EQ(1, message1.unknown_fields().field_count());
+  const UnknownField& field = message1.unknown_fields().field(0);
+  ASSERT_EQ(2, field.varint_size());
+  EXPECT_EQ(1, field.varint(0));
+  EXPECT_EQ(2, field.varint(1));
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST(ReflectionOpsTest, MergeFromSelf) {
+  // Note:  Copy is implemented in terms of Merge() so technically the Copy
+  //   test already tested most of this.
+
+  unittest::TestAllTypes message;
+
+  EXPECT_DEATH(
+    ReflectionOps::Merge(message.descriptor(), *message.GetReflection(),
+                         message.GetReflection()),
+    "&from");
+}
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+TEST(ReflectionOpsTest, Clear) {
+  unittest::TestAllTypes message;
+
+  TestUtil::SetAllFields(&message);
+
+  ReflectionOps::Clear(message.descriptor(), message.GetReflection());
+
+  TestUtil::ExpectClear(message);
+
+  // Check that getting embedded messages returns the objects created during
+  // SetAllFields() rather than default instances.
+  EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+            &message.optionalgroup());
+  EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &message.optional_nested_message());
+  EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+            &message.optional_foreign_message());
+  EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+            &message.optional_import_message());
+}
+
+TEST(ReflectionOpsTest, ClearExtensions) {
+  unittest::TestAllExtensions message;
+
+  TestUtil::SetAllExtensions(&message);
+
+  ReflectionOps::Clear(message.descriptor(), message.GetReflection());
+
+  TestUtil::ExpectExtensionsClear(message);
+
+  // Check that getting embedded messages returns the objects created during
+  // SetAllExtensions() rather than default instances.
+  EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
+            &message.GetExtension(unittest::optionalgroup_extension));
+  EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &message.GetExtension(unittest::optional_nested_message_extension));
+  EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+            &message.GetExtension(
+              unittest::optional_foreign_message_extension));
+  EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+            &message.GetExtension(unittest::optional_import_message_extension));
+}
+
+TEST(ReflectionOpsTest, ClearUnknown) {
+  // Test that the message's UnknownFieldSet is correctly cleared.
+  unittest::TestEmptyMessage message;
+  message.mutable_unknown_fields()->AddField(1234)->add_varint(1);
+
+  ReflectionOps::Clear(message.descriptor(), message.GetReflection());
+
+  EXPECT_EQ(0, message.unknown_fields().field_count());
+}
+
+TEST(ReflectionOpsTest, DiscardUnknownFields) {
+  unittest::TestAllTypes message;
+  TestUtil::SetAllFields(&message);
+
+  // Set some unknown fields in message.
+  message.mutable_unknown_fields()
+        ->AddField(123456)
+        ->add_varint(654321);
+  message.mutable_optional_nested_message()
+        ->mutable_unknown_fields()
+        ->AddField(123456)
+        ->add_varint(654321);
+  message.mutable_repeated_nested_message(0)
+        ->mutable_unknown_fields()
+        ->AddField(123456)
+        ->add_varint(654321);
+
+  EXPECT_EQ(1, message.unknown_fields().field_count());
+  EXPECT_EQ(1, message.optional_nested_message()
+                      .unknown_fields().field_count());
+  EXPECT_EQ(1, message.repeated_nested_message(0)
+                      .unknown_fields().field_count());
+
+  // Discard them.
+  ReflectionOps::DiscardUnknownFields(message.GetDescriptor(),
+                                      message.GetReflection());
+  TestUtil::ExpectAllFieldsSet(message);
+
+  EXPECT_EQ(0, message.unknown_fields().field_count());
+  EXPECT_EQ(0, message.optional_nested_message()
+                      .unknown_fields().field_count());
+  EXPECT_EQ(0, message.repeated_nested_message(0)
+                      .unknown_fields().field_count());
+}
+
+TEST(ReflectionOpsTest, DiscardUnknownExtensions) {
+  unittest::TestAllExtensions message;
+  TestUtil::SetAllExtensions(&message);
+
+  // Set some unknown fields.
+  message.mutable_unknown_fields()
+        ->AddField(123456)
+        ->add_varint(654321);
+  message.MutableExtension(unittest::optional_nested_message_extension)
+        ->mutable_unknown_fields()
+        ->AddField(123456)
+        ->add_varint(654321);
+  message.MutableExtension(unittest::repeated_nested_message_extension, 0)
+        ->mutable_unknown_fields()
+        ->AddField(123456)
+        ->add_varint(654321);
+
+  EXPECT_EQ(1, message.unknown_fields().field_count());
+  EXPECT_EQ(1,
+    message.GetExtension(unittest::optional_nested_message_extension)
+           .unknown_fields().field_count());
+  EXPECT_EQ(1,
+    message.GetExtension(unittest::repeated_nested_message_extension, 0)
+           .unknown_fields().field_count());
+
+  // Discard them.
+  ReflectionOps::DiscardUnknownFields(message.GetDescriptor(),
+                                      message.GetReflection());
+  TestUtil::ExpectAllExtensionsSet(message);
+
+  EXPECT_EQ(0, message.unknown_fields().field_count());
+  EXPECT_EQ(0,
+    message.GetExtension(unittest::optional_nested_message_extension)
+           .unknown_fields().field_count());
+  EXPECT_EQ(0,
+    message.GetExtension(unittest::repeated_nested_message_extension, 0)
+           .unknown_fields().field_count());
+}
+
+TEST(ReflectionOpsTest, IsInitialized) {
+  unittest::TestRequired message;
+
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
+                                            *message.GetReflection()));
+  message.set_a(1);
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
+                                            *message.GetReflection()));
+  message.set_b(2);
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
+                                            *message.GetReflection()));
+  message.set_c(3);
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message.descriptor(),
+                                           *message.GetReflection()));
+}
+
+TEST(ReflectionOpsTest, ForeignIsInitialized) {
+  unittest::TestRequiredForeign message;
+
+  // Starts out initialized because the foreign message is itself an optional
+  // field.
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message.descriptor(),
+                                           *message.GetReflection()));
+
+  // Once we create that field, the message is no longer initialized.
+  message.mutable_optional_message();
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
+                                            *message.GetReflection()));
+
+  // 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()));
+
+  // 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()));
+
+  // 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()));
+}
+
+TEST(ReflectionOpsTest, ExtensionIsInitialized) {
+  unittest::TestAllExtensions message;
+
+  // Starts out initialized because the foreign message is itself an optional
+  // field.
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message.descriptor(),
+                                           *message.GetReflection()));
+
+  // Once we create that field, the message is no longer initialized.
+  message.MutableExtension(unittest::TestRequired::single);
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
+                                            *message.GetReflection()));
+
+  // 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()));
+
+  // Add a repeated version of the message.  No longer initialized.
+  message.AddExtension(unittest::TestRequired::multi);
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message.descriptor(),
+                                            *message.GetReflection()));
+
+  // 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()));
+}
+
+static string FindInitializationErrors(const Message& message) {
+  vector<string> errors;
+  ReflectionOps::FindInitializationErrors(message.GetDescriptor(),
+                                          *message.GetReflection(),
+                                          "", &errors);
+  return JoinStrings(errors, ",");
+}
+
+TEST(ReflectionOpsTest, FindInitializationErrors) {
+  unittest::TestRequired message;
+  EXPECT_EQ("a,b,c", FindInitializationErrors(message));
+}
+
+TEST(ReflectionOpsTest, FindForeignInitializationErrors) {
+  unittest::TestRequiredForeign message;
+  message.mutable_optional_message();
+  message.add_repeated_message();
+  message.add_repeated_message();
+  EXPECT_EQ("optional_message.a,"
+            "optional_message.b,"
+            "optional_message.c,"
+            "repeated_message[0].a,"
+            "repeated_message[0].b,"
+            "repeated_message[0].c,"
+            "repeated_message[1].a,"
+            "repeated_message[1].b,"
+            "repeated_message[1].c",
+            FindInitializationErrors(message));
+}
+
+TEST(ReflectionOpsTest, FindExtensionInitializationErrors) {
+  unittest::TestAllExtensions message;
+  message.MutableExtension(unittest::TestRequired::single);
+  message.AddExtension(unittest::TestRequired::multi);
+  message.AddExtension(unittest::TestRequired::multi);
+  EXPECT_EQ("(protobuf_unittest.TestRequired.single).a,"
+            "(protobuf_unittest.TestRequired.single).b,"
+            "(protobuf_unittest.TestRequired.single).c,"
+            "(protobuf_unittest.TestRequired.multi)[0].a,"
+            "(protobuf_unittest.TestRequired.multi)[0].b,"
+            "(protobuf_unittest.TestRequired.multi)[0].c,"
+            "(protobuf_unittest.TestRequired.multi)[1].a,"
+            "(protobuf_unittest.TestRequired.multi)[1].b,"
+            "(protobuf_unittest.TestRequired.multi)[1].c",
+            FindInitializationErrors(message));
+}
+
+}  // namespace
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc
new file mode 100644
index 0000000..53a3c95
--- /dev/null
+++ b/src/google/protobuf/repeated_field.cc
@@ -0,0 +1,41 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/repeated_field.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+GenericRepeatedField::~GenericRepeatedField() {}
+
+} // namespace internal
+
+template <>
+void RepeatedPtrField<string>::Clear() {
+  for (int i = 0; i < current_size_; i++) {
+    elements_[i]->clear();
+  }
+  current_size_ = 0;
+}
+
+}  // namespace protobuf
+
+}  // namespace google
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
new file mode 100644
index 0000000..3368e8b
--- /dev/null
+++ b/src/google/protobuf/repeated_field.h
@@ -0,0 +1,782 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// RepeatedField and RepeatedPtrField are used by generated protocol message
+// classes to manipulate repeated fields.  These classes are very similar to
+// STL's vector, but include a number of optimizations found to be useful
+// specifically in the case of Protocol Buffers.  RepeatedPtrField is
+// particularly different from STL vector as it manages ownership of the
+// pointers that it contains.
+//
+// Typically, clients should not need to access RepeatedField objects directly,
+// but should instead use the accessor functions generated automatically by the
+// protocol compiler.
+
+#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
+#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
+
+#include <string>
+#include <iterator>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/message.h>
+
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+// DO NOT USE GenericRepeatedField; it should be considered a private detail
+// of RepeatedField/RepeatedPtrField that may be removed in the future.
+// GeneratedMessageReflection needs to manipulate repeated fields in a
+// generic way, so we have them implement this interface.  This should ONLY
+// be used by GeneratedMessageReflection.  This would normally be very bad
+// design but GeneratedMessageReflection is a big efficiency hack anyway.
+//
+// TODO(kenton):  Implement something like Jeff's ProtoVoidPtrArray change.
+//   Then, get rid of GenericRepeatedField.
+class LIBPROTOBUF_EXPORT GenericRepeatedField {
+ public:
+  inline GenericRepeatedField() {}
+  virtual ~GenericRepeatedField();
+
+ private:
+  // We only want GeneratedMessageReflection to see and use these, so we
+  // make them private.  Yes, it is valid C++ for a subclass to implement
+  // a virtual method which is private in the superclass.  Crazy, huh?
+  friend class GeneratedMessageReflection;
+
+  virtual const void* GenericGet(int index) const = 0;
+  virtual void* GenericMutable(int index) = 0;
+  virtual void* GenericAdd() = 0;
+  virtual void GenericClear() = 0;
+  virtual int GenericSize() const = 0;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GenericRepeatedField);
+};
+
+}  // namespace internal
+
+// RepeatedField is used to represent repeated fields of a primitive type (in
+// other words, everything except strings and nested Messages).  Most users will
+// not ever use a RepeatedField directly; they will use the get-by-index,
+// set-by-index, and add accessors that are generated for all repeated fields.
+template <typename Element>
+class RepeatedField : public internal::GenericRepeatedField {
+ public:
+  RepeatedField();
+  ~RepeatedField();
+
+  int size() const;
+
+  Element Get(int index) const;
+  Element* Mutable(int index);
+  void Set(int index, Element value);
+  void Add(Element value);
+  // Remove the last element in the array.
+  // We don't provide a way to remove any element other than the last
+  // because it invites inefficient use, such as O(n^2) filtering loops
+  // that should have been O(n).  If you want to remove an element other
+  // than the last, the best way to do it is to re-arrange the elements
+  // so that the one you want removed is at the end, then call RemoveLast().
+  void RemoveLast();
+  void Clear();
+  void MergeFrom(const RepeatedField& other);
+
+  // Reserve space to expand the field to at least the given size.  If the
+  // array is grown, it will always be at least doubled in size.
+  void Reserve(int new_size);
+
+  // Gets the underlying array.  This pointer is possibly invalidated by
+  // any add or remove operation.
+  Element* mutable_data();
+  const Element* data() const;
+
+  // Swap entire contents with "other".
+  void Swap(RepeatedField* other);
+
+  // STL-like iterator support
+  typedef Element* iterator;
+  typedef const Element* const_iterator;
+
+  iterator begin();
+  const_iterator begin() const;
+  iterator end();
+  const_iterator end() const;
+
+ private:  // See GenericRepeatedField for why this is private.
+  // implements GenericRepeatedField ---------------------------------
+  const void* GenericGet(int index) const;
+  void* GenericMutable(int index);
+  void* GenericAdd();
+  void GenericClear();
+  int GenericSize() const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedField);
+
+  static const int kInitialSize = 4;
+
+  Element* elements_;
+  int      current_size_;
+  int      total_size_;
+
+  Element  initial_space_[kInitialSize];
+};
+
+namespace internal {
+template <typename It> class RepeatedPtrIterator;
+}  // namespace internal
+
+// RepeatedPtrField is like RepeatedField, but used for repeated strings or
+// Messages.
+template <typename Element>
+class RepeatedPtrField : public internal::GenericRepeatedField {
+ public:
+  RepeatedPtrField();
+
+  // This constructor is only defined for RepeatedPtrField<Message>.
+  // When a RepeatedPtrField is created using this constructor,
+  // prototype->New() will be called to allocate new elements, rather than
+  // just using the "new" operator.  This is useful for the implementation
+  // of DynamicMessage, but is not used by normal generated messages.
+  explicit RepeatedPtrField(const Message* prototype);
+
+  ~RepeatedPtrField();
+
+  // Returns the prototype if one was passed to the constructor.
+  const Message* prototype() const;
+
+  int size() const;
+
+  const Element& Get(int index) const;
+  Element* Mutable(int index);
+  Element* Add();
+  void RemoveLast();  // Remove the last element in the array.
+  void Clear();
+  void MergeFrom(const RepeatedPtrField& other);
+
+  // Reserve space to expand the field to at least the given size.  This only
+  // resizes the pointer array; it doesn't allocate any objects.  If the
+  // array is grown, it will always be at least doubled in size.
+  void Reserve(int new_size);
+
+  // Gets the underlying array.  This pointer is possibly invalidated by
+  // any add or remove operation.
+  Element** mutable_data();
+  const Element* const* data() const;
+
+  // Swap entire contents with "other".
+  void Swap(RepeatedPtrField* other);
+
+  // STL-like iterator support
+  typedef internal::RepeatedPtrIterator<Element**> iterator;
+  typedef internal::RepeatedPtrIterator<const Element* const*> const_iterator;
+
+  iterator begin();
+  const_iterator begin() const;
+  iterator end();
+  const_iterator end() const;
+
+  // Advanced memory management --------------------------------------
+  // When hardcore memory management becomes necessary -- as it often
+  // does here at Google -- the following methods may be useful.
+
+  // Add an already-allocated object, passing ownership to the
+  // RepeatedPtrField.
+  void AddAllocated(Element* value);
+  // Remove the last element and return it, passing ownership to the
+  // caller.
+  // Requires:  size() > 0
+  Element* ReleaseLast();
+
+  // When elements are removed by calls to RemoveLast() or Clear(), they
+  // are not actually freed.  Instead, they are cleared and kept so that
+  // they can be reused later.  This can save lots of CPU time when
+  // repeatedly reusing a protocol message for similar purposes.
+  //
+  // Really, extremely hardcore programs may actually want to manipulate
+  // these objects to better-optimize memory management.  These methods
+  // allow that.
+
+  // Get the number of cleared objects that are currently being kept
+  // around for reuse.
+  int ClearedCount();
+  // Add an element to the pool of cleared objects, passing ownership to
+  // the RepeatedPtrField.  The element must be cleared prior to calling
+  // this method.
+  void AddCleared(Element* value);
+  // Remove a single element from the cleared pool and return it, passing
+  // ownership to the caller.  The element is guaranteed to be cleared.
+  // Requires:  ClearedCount() > 0
+  Element* ReleaseCleared();
+
+ private:  // See GenericRepeatedField for why this is private.
+  // implements GenericRepeatedField ---------------------------------
+  const void* GenericGet(int index) const;
+  void* GenericMutable(int index);
+  void* GenericAdd();
+  void GenericClear();
+  int GenericSize() const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField);
+
+  static const int kInitialSize = 4;
+
+  // prototype_ is used for RepeatedPtrField<Message> only (see constructor).
+  const Message* prototype_;
+
+  Element** elements_;
+  int       current_size_;
+  int       allocated_size_;
+  int       total_size_;
+
+  Element*  initial_space_[kInitialSize];
+
+  Element* NewElement();
+};
+
+// implementation ====================================================
+
+template <typename Element>
+inline RepeatedField<Element>::RepeatedField()
+  : elements_(initial_space_),
+    current_size_(0),
+    total_size_(kInitialSize) {
+}
+
+template <typename Element>
+RepeatedField<Element>::~RepeatedField() {
+  if (elements_ != initial_space_) {
+    delete [] elements_;
+  }
+}
+
+template <typename Element>
+inline int RepeatedField<Element>::size() const {
+  return current_size_;
+}
+
+
+template <typename Element>
+inline Element RepeatedField<Element>::Get(int index) const {
+  GOOGLE_DCHECK_LT(index, size());
+  return elements_[index];
+}
+
+template <typename Element>
+inline Element* RepeatedField<Element>::Mutable(int index) {
+  GOOGLE_DCHECK_LT(index, size());
+  return elements_ + index;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Set(int index, Element value) {
+  GOOGLE_DCHECK_LT(index, size());
+  elements_[index] = value;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Add(Element value) {
+  if (current_size_ == total_size_) Reserve(total_size_ + 1);
+  elements_[current_size_++] = value;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::RemoveLast() {
+  GOOGLE_DCHECK_GT(current_size_, 0);
+  --current_size_;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Clear() {
+  current_size_ = 0;
+}
+
+template <typename Element>
+void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
+  Reserve(current_size_ + other.current_size_);
+  memcpy(elements_ + current_size_, other.elements_,
+         sizeof(Element) * other.current_size_);
+  current_size_ += other.current_size_;
+}
+
+template <typename Element>
+inline Element* RepeatedField<Element>::mutable_data() {
+  return elements_;
+}
+
+template <typename Element>
+inline const Element* RepeatedField<Element>::data() const {
+  return elements_;
+}
+
+
+template <typename Element>
+void RepeatedField<Element>::Swap(RepeatedField* other) {
+  Element* swap_elements     = elements_;
+  int      swap_current_size = current_size_;
+  int      swap_total_size   = total_size_;
+  // We may not be using initial_space_ but it's not worth checking.  Just
+  // copy it anyway.
+  Element swap_initial_space[kInitialSize];
+  memcpy(swap_initial_space, initial_space_, sizeof(initial_space_));
+
+  elements_     = other->elements_;
+  current_size_ = other->current_size_;
+  total_size_   = other->total_size_;
+  memcpy(initial_space_, other->initial_space_, sizeof(initial_space_));
+
+  other->elements_     = swap_elements;
+  other->current_size_ = swap_current_size;
+  other->total_size_   = swap_total_size;
+  memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space));
+
+  if (elements_ == other->initial_space_) {
+    elements_ = initial_space_;
+  }
+  if (other->elements_ == initial_space_) {
+    other->elements_ = other->initial_space_;
+  }
+}
+
+template <typename Element>
+inline typename RepeatedField<Element>::iterator
+RepeatedField<Element>::begin() {
+  return elements_;
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::begin() const {
+  return elements_;
+}
+template <typename Element>
+inline typename RepeatedField<Element>::iterator
+RepeatedField<Element>::end() {
+  return elements_ + current_size_;
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::end() const {
+  return elements_ + current_size_;
+}
+
+
+template <typename Element>
+const void* RepeatedField<Element>::GenericGet(int index) const {
+  GOOGLE_DCHECK_LT(index, size());
+  return elements_ + index;
+}
+
+template <typename Element>
+void* RepeatedField<Element>::GenericMutable(int index) {
+  return Mutable(index);
+}
+
+template <typename Element>
+void* RepeatedField<Element>::GenericAdd() {
+  Add(Element());
+  return Mutable(current_size_ - 1);
+}
+
+template <typename Element>
+void RepeatedField<Element>::GenericClear() {
+  Clear();
+}
+
+template <typename Element>
+int RepeatedField<Element>::GenericSize() const {
+  return size();
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Reserve(int new_size) {
+  if (total_size_ >= new_size) return;
+
+  Element* old_elements = elements_;
+  total_size_ = max(total_size_ * 2, new_size);
+  elements_ = new Element[total_size_];
+  memcpy(elements_, old_elements, current_size_ * sizeof(elements_[0]));
+  if (old_elements != initial_space_) {
+    delete [] old_elements;
+  }
+}
+
+// -------------------------------------------------------------------
+
+template <typename Element>
+inline RepeatedPtrField<Element>::RepeatedPtrField()
+  : prototype_(NULL),
+    elements_(initial_space_),
+    current_size_(0),
+    allocated_size_(0),
+    total_size_(kInitialSize) {
+}
+
+template <>
+inline RepeatedPtrField<Message>::RepeatedPtrField(const Message* prototype)
+  : prototype_(prototype),
+    elements_(initial_space_),
+    current_size_(0),
+    allocated_size_(0),
+    total_size_(kInitialSize) {
+}
+
+template <typename Element>
+RepeatedPtrField<Element>::~RepeatedPtrField() {
+  for (int i = 0; i < allocated_size_; i++) {
+    delete elements_[i];
+  }
+  if (elements_ != initial_space_) {
+    delete [] elements_;
+  }
+}
+
+template <>
+inline const Message* RepeatedPtrField<Message>::prototype() const {
+  return prototype_;
+}
+
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::size() const {
+  return current_size_;
+}
+
+
+template <typename Element>
+inline const Element& RepeatedPtrField<Element>::Get(int index) const {
+  GOOGLE_DCHECK_LT(index, size());
+  return *elements_[index];
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::Mutable(int index) {
+  GOOGLE_DCHECK_LT(index, size());
+  return elements_[index];
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::Add() {
+  if (current_size_ < allocated_size_) return elements_[current_size_++];
+  if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
+  ++allocated_size_;
+  return elements_[current_size_++] = NewElement();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::RemoveLast() {
+  GOOGLE_DCHECK_GT(current_size_, 0);
+  elements_[--current_size_]->Clear();
+}
+
+template <>
+inline void RepeatedPtrField<string>::RemoveLast() {
+  GOOGLE_DCHECK_GT(current_size_, 0);
+  elements_[--current_size_]->clear();
+}
+
+template <typename Element>
+void RepeatedPtrField<Element>::Clear() {
+  for (int i = 0; i < current_size_; i++) {
+    elements_[i]->Clear();
+  }
+  current_size_ = 0;
+}
+
+// Specialization defined in repeated_field.cc.
+template <>
+void LIBPROTOBUF_EXPORT RepeatedPtrField<string>::Clear();
+
+template <typename Element>
+void RepeatedPtrField<Element>::MergeFrom(const RepeatedPtrField& other) {
+  Reserve(current_size_ + other.current_size_);
+  for (int i = 0; i < other.current_size_; i++) {
+    Add()->MergeFrom(other.Get(i));
+  }
+}
+
+template <>
+inline void RepeatedPtrField<string>::MergeFrom(const RepeatedPtrField& other) {
+  Reserve(current_size_ + other.current_size_);
+  for (int i = 0; i < other.current_size_; i++) {
+    Add()->assign(other.Get(i));
+  }
+}
+
+
+template <typename Element>
+inline Element** RepeatedPtrField<Element>::mutable_data() {
+  return elements_;
+}
+
+template <typename Element>
+inline const Element* const* RepeatedPtrField<Element>::data() const {
+  return elements_;
+}
+
+
+template <typename Element>
+void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
+  Element** swap_elements       = elements_;
+  int       swap_current_size   = current_size_;
+  int       swap_allocated_size = allocated_size_;
+  int       swap_total_size     = total_size_;
+  // We may not be using initial_space_ but it's not worth checking.  Just
+  // copy it anyway.
+  Element* swap_initial_space[kInitialSize];
+  memcpy(swap_initial_space, initial_space_, sizeof(initial_space_));
+
+  elements_       = other->elements_;
+  current_size_   = other->current_size_;
+  allocated_size_ = other->allocated_size_;
+  total_size_     = other->total_size_;
+  memcpy(initial_space_, other->initial_space_, sizeof(initial_space_));
+
+  other->elements_       = swap_elements;
+  other->current_size_   = swap_current_size;
+  other->allocated_size_ = swap_allocated_size;
+  other->total_size_     = swap_total_size;
+  memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space));
+
+  if (elements_ == other->initial_space_) {
+    elements_ = initial_space_;
+  }
+  if (other->elements_ == initial_space_) {
+    other->elements_ = other->initial_space_;
+  }
+}
+
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
+  if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
+  // We don't care about the order of cleared elements, so if there's one
+  // in the way, just move it to the back of the array.
+  if (current_size_ < allocated_size_) {
+    elements_[allocated_size_] = elements_[current_size_];
+  }
+  ++allocated_size_;
+  elements_[current_size_++] = value;
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::ReleaseLast() {
+  GOOGLE_DCHECK_GT(current_size_, 0);
+  Element* result = elements_[--current_size_];
+  --allocated_size_;
+  if (current_size_ < allocated_size_) {
+    // There are cleared elements on the end; replace the removed element
+    // with the last allocated element.
+    elements_[current_size_] = elements_[allocated_size_];
+  }
+  return result;
+}
+
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::ClearedCount() {
+  return allocated_size_ - current_size_;
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
+  if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
+  elements_[allocated_size_++] = value;
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
+  GOOGLE_DCHECK_GT(allocated_size_, current_size_);
+  return elements_[--allocated_size_];
+}
+
+
+template <typename Element>
+const void* RepeatedPtrField<Element>::GenericGet(int index) const {
+  return &Get(index);
+}
+
+template <typename Element>
+void* RepeatedPtrField<Element>::GenericMutable(int index) {
+  return Mutable(index);
+}
+
+template <typename Element>
+void* RepeatedPtrField<Element>::GenericAdd() {
+  return Add();
+}
+
+template <typename Element>
+void RepeatedPtrField<Element>::GenericClear() {
+  Clear();
+}
+
+template <typename Element>
+int RepeatedPtrField<Element>::GenericSize() const {
+  return size();
+}
+
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::Reserve(int new_size) {
+  if (total_size_ >= new_size) return;
+
+  Element** old_elements = elements_;
+  total_size_ = max(total_size_ * 2, new_size);
+  elements_ = new Element*[total_size_];
+  memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0]));
+  if (old_elements != initial_space_) {
+    delete [] old_elements;
+  }
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::NewElement() {
+  return new Element;
+}
+
+// RepeatedPtrField<Message> is alowed but requires a prototype since Message
+// is abstract.
+template <>
+inline Message* RepeatedPtrField<Message>::NewElement() {
+  return prototype_->New();
+}
+
+// -------------------------------------------------------------------
+
+namespace internal {
+
+// STL-like iterator implementation for RepeatedPtrField.  You should not
+// refer to this class directly; use RepeatedPtrField<T>::iterator instead.
+//
+// The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T**>, is
+// very similar to iterator_ptr<> in util/gtl/iterator_adaptors-inl.h,
+// but adds random-access operators and is slightly more specialized
+// for using T** as its base type. I didn't re-use the other class to
+// avoid an extra dependency.
+//
+// This code stolen from net/proto/proto-array-internal.h by Jeffrey Yasskin
+// (jyasskin@google.com).
+template<typename It>
+class RepeatedPtrIterator
+    : public std::iterator<
+          std::random_access_iterator_tag,
+          typename internal::remove_pointer<
+              typename internal::remove_pointer<It>::type>::type> {
+ public:
+  typedef RepeatedPtrIterator<It> iterator;
+  typedef typename iterator::reference reference;
+  typedef typename iterator::pointer pointer;
+  typedef typename iterator::difference_type difference_type;
+
+  RepeatedPtrIterator() : it_(NULL) {}
+  explicit RepeatedPtrIterator(const It& it) : it_(it) {}
+
+  // Allow "upcasting" from RepeatedPtrIterator<T**> to
+  // RepeatedPtrIterator<const T*const*>.
+  template<typename OtherIt>
+  RepeatedPtrIterator(const RepeatedPtrIterator<OtherIt>& other)
+      : it_(other.base()) {}
+
+  // Provide access to the wrapped iterator.
+  const It& base() const { return it_; }
+
+  // dereferenceable
+  reference operator*() const { return **it_; }
+  pointer   operator->() const { return &(operator*()); }
+
+  // {inc,dec}rementable
+  iterator& operator++() { ++it_; return *this; }
+  iterator  operator++(int) { return iterator(it_++); }
+  iterator& operator--() { --it_; return *this; }
+  iterator  operator--(int) { return iterator(it_--); }
+
+  // equality_comparable
+  bool operator==(const iterator& x) const { return it_ == x.it_; }
+  bool operator!=(const iterator& x) const { return it_ != x.it_; }
+
+  // less_than_comparable
+  bool operator<(const iterator& x) const { return it_ < x.it_; }
+  bool operator<=(const iterator& x) const { return it_ <= x.it_; }
+  bool operator>(const iterator& x) const { return it_ > x.it_; }
+  bool operator>=(const iterator& x) const { return it_ >= x.it_; }
+
+  // addable, subtractable
+  iterator& operator+=(difference_type d) {
+    it_ += d;
+    return *this;
+  }
+  friend iterator operator+(iterator it, difference_type d) {
+    it += d;
+    return it;
+  }
+  friend iterator operator+(difference_type d, iterator it) {
+    it += d;
+    return it;
+  }
+  iterator& operator-=(difference_type d) {
+    it_ -= d;
+    return *this;
+  }
+  friend iterator operator-(iterator it, difference_type d) {
+    it -= d;
+    return it;
+  }
+
+  // indexable
+  reference operator[](difference_type d) const { return *(*this + d); }
+
+  // random access iterator
+  difference_type operator-(const iterator& x) const { return it_ - x.it_; }
+
+ private:
+  // The internal iterator.
+  It it_;
+};
+
+}  // namespace internal
+
+template <typename Element>
+inline typename RepeatedPtrField<Element>::iterator
+RepeatedPtrField<Element>::begin() {
+  return iterator(elements_);
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_iterator
+RepeatedPtrField<Element>::begin() const {
+  return iterator(elements_);
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::iterator
+RepeatedPtrField<Element>::end() {
+  return iterator(elements_ + current_size_);
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_iterator
+RepeatedPtrField<Element>::end() const {
+  return iterator(elements_ + current_size_);
+}
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
new file mode 100644
index 0000000..eb9b096
--- /dev/null
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -0,0 +1,603 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// TODO(kenton):  Improve this unittest to bring it up to the standards of
+//   other proto2 unittests.
+
+#include <algorithm>
+
+#include <google/protobuf/repeated_field.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+// Test operations on a RepeatedField which is small enough that it does
+// not allocate a separate array for storage.
+TEST(RepeatedField, Small) {
+  RepeatedField<int> field;
+
+  EXPECT_EQ(field.size(), 0);
+
+  field.Add(5);
+
+  EXPECT_EQ(field.size(), 1);
+  EXPECT_EQ(field.Get(0), 5);
+
+  field.Add(42);
+
+  EXPECT_EQ(field.size(), 2);
+  EXPECT_EQ(field.Get(0), 5);
+  EXPECT_EQ(field.Get(1), 42);
+
+  field.Set(1, 23);
+
+  EXPECT_EQ(field.size(), 2);
+  EXPECT_EQ(field.Get(0), 5);
+  EXPECT_EQ(field.Get(1), 23);
+
+  field.RemoveLast();
+
+  EXPECT_EQ(field.size(), 1);
+  EXPECT_EQ(field.Get(0), 5);
+
+  field.Clear();
+
+  EXPECT_EQ(field.size(), 0);
+}
+
+// Test operations on a RepeatedField which is large enough to allocate a
+// separate array.
+TEST(RepeatedField, Large) {
+  RepeatedField<int> field;
+
+  for (int i = 0; i < 16; i++) {
+    field.Add(i * i);
+  }
+
+  EXPECT_EQ(field.size(), 16);
+
+  for (int i = 0; i < 16; i++) {
+    EXPECT_EQ(field.Get(i), i * i);
+  }
+}
+
+// Test swapping between various types of RepeatedFields.
+TEST(RepeatedField, SwapSmallSmall) {
+  RepeatedField<int> field1;
+  RepeatedField<int> field2;
+
+  field1.Add(5);
+  field1.Add(42);
+
+  field1.Swap(&field2);
+
+  EXPECT_EQ(field1.size(), 0);
+  EXPECT_EQ(field2.size(), 2);
+  EXPECT_EQ(field2.Get(0), 5);
+  EXPECT_EQ(field2.Get(1), 42);
+}
+
+TEST(RepeatedField, SwapLargeSmall) {
+  RepeatedField<int> field1;
+  RepeatedField<int> field2;
+
+  for (int i = 0; i < 16; i++) {
+    field1.Add(i * i);
+  }
+  field2.Add(5);
+  field2.Add(42);
+  field1.Swap(&field2);
+
+  EXPECT_EQ(field1.size(), 2);
+  EXPECT_EQ(field1.Get(0), 5);
+  EXPECT_EQ(field1.Get(1), 42);
+  EXPECT_EQ(field2.size(), 16);
+  for (int i = 0; i < 16; i++) {
+    EXPECT_EQ(field2.Get(i), i * i);
+  }
+}
+
+TEST(RepeatedField, SwapLargeLarge) {
+  RepeatedField<int> field1;
+  RepeatedField<int> field2;
+
+  field1.Add(5);
+  field1.Add(42);
+  for (int i = 0; i < 16; i++) {
+    field1.Add(i);
+    field2.Add(i * i);
+  }
+  field2.Swap(&field1);
+
+  EXPECT_EQ(field1.size(), 16);
+  for (int i = 0; i < 16; i++) {
+    EXPECT_EQ(field1.Get(i), i * i);
+  }
+  EXPECT_EQ(field2.size(), 18);
+  EXPECT_EQ(field2.Get(0), 5);
+  EXPECT_EQ(field2.Get(1), 42);
+  for (int i = 2; i < 18; i++) {
+    EXPECT_EQ(field2.Get(i), i - 2);
+  }
+}
+
+// Determines how much space was reserved by the given field by adding elements
+// to it until it re-allocates its space.
+static int ReservedSpace(RepeatedField<int>* field) {
+  const int* ptr = field->data();
+  do {
+    field->Add(0);
+  } while (field->data() == ptr);
+
+  return field->size() - 1;
+}
+
+TEST(RepeatedField, ReserveMoreThanDouble) {
+  // Reserve more than double the previous space in the field and expect the
+  // field to reserve exactly the amount specified.
+  RepeatedField<int> field;
+  field.Reserve(20);
+
+  EXPECT_EQ(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedField, ReserveLessThanDouble) {
+  // Reserve less than double the previous space in the field and expect the
+  // field to grow by double instead.
+  RepeatedField<int> field;
+  field.Reserve(20);
+  field.Reserve(30);
+
+  EXPECT_EQ(40, ReservedSpace(&field));
+}
+
+TEST(RepeatedField, ReserveLessThanExisting) {
+  // Reserve less than the previous space in the field and expect the
+  // field to not re-allocate at all.
+  RepeatedField<int> field;
+  field.Reserve(20);
+  const int* previous_ptr = field.data();
+  field.Reserve(10);
+
+  EXPECT_EQ(previous_ptr, field.data());
+  EXPECT_EQ(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedField, MergeFrom) {
+  RepeatedField<int> source, destination;
+
+  source.Add(4);
+  source.Add(5);
+
+  destination.Add(1);
+  destination.Add(2);
+  destination.Add(3);
+
+  destination.MergeFrom(source);
+
+  ASSERT_EQ(5, destination.size());
+
+  EXPECT_EQ(1, destination.Get(0));
+  EXPECT_EQ(2, destination.Get(1));
+  EXPECT_EQ(3, destination.Get(2));
+  EXPECT_EQ(4, destination.Get(3));
+  EXPECT_EQ(5, destination.Get(4));
+}
+
+TEST(RepeatedField, MutableDataIsMutable) {
+  RepeatedField<int> field;
+  field.Add(1);
+  EXPECT_EQ(1, field.Get(0));
+  // The fact that this line compiles would be enough, but we'll check the
+  // value anyway.
+  *field.mutable_data() = 2;
+  EXPECT_EQ(2, field.Get(0));
+}
+
+// ===================================================================
+// RepeatedPtrField tests.  These pretty much just mirror the RepeatedField
+// tests above.
+
+TEST(RepeatedPtrField, Small) {
+  RepeatedPtrField<string> field;
+
+  EXPECT_EQ(field.size(), 0);
+
+  field.Add()->assign("foo");
+
+  EXPECT_EQ(field.size(), 1);
+  EXPECT_EQ(field.Get(0), "foo");
+
+  field.Add()->assign("bar");
+
+  EXPECT_EQ(field.size(), 2);
+  EXPECT_EQ(field.Get(0), "foo");
+  EXPECT_EQ(field.Get(1), "bar");
+
+  field.Mutable(1)->assign("baz");
+
+  EXPECT_EQ(field.size(), 2);
+  EXPECT_EQ(field.Get(0), "foo");
+  EXPECT_EQ(field.Get(1), "baz");
+
+  field.RemoveLast();
+
+  EXPECT_EQ(field.size(), 1);
+  EXPECT_EQ(field.Get(0), "foo");
+
+  field.Clear();
+
+  EXPECT_EQ(field.size(), 0);
+}
+
+TEST(RepeatedPtrField, Large) {
+  RepeatedPtrField<string> field;
+
+  for (int i = 0; i < 16; i++) {
+    *field.Add() += 'a' + i;
+  }
+
+  EXPECT_EQ(field.size(), 16);
+
+  for (int i = 0; i < 16; i++) {
+    EXPECT_EQ(field.Get(i).size(), 1);
+    EXPECT_EQ(field.Get(i)[0], 'a' + i);
+  }
+}
+
+TEST(RepeatedPtrField, SwapSmallSmall) {
+  RepeatedPtrField<string> field1;
+  RepeatedPtrField<string> field2;
+
+  field1.Add()->assign("foo");
+  field1.Add()->assign("bar");
+  field1.Swap(&field2);
+
+  EXPECT_EQ(field1.size(), 0);
+  EXPECT_EQ(field2.size(), 2);
+  EXPECT_EQ(field2.Get(0), "foo");
+  EXPECT_EQ(field2.Get(1), "bar");
+}
+
+TEST(RepeatedPtrField, SwapLargeSmall) {
+  RepeatedPtrField<string> field1;
+  RepeatedPtrField<string> field2;
+
+  field2.Add()->assign("foo");
+  field2.Add()->assign("bar");
+  for (int i = 0; i < 16; i++) {
+    *field1.Add() += 'a' + i;
+  }
+  field1.Swap(&field2);
+
+  EXPECT_EQ(field1.size(), 2);
+  EXPECT_EQ(field1.Get(0), "foo");
+  EXPECT_EQ(field1.Get(1), "bar");
+  EXPECT_EQ(field2.size(), 16);
+  for (int i = 0; i < 16; i++) {
+    EXPECT_EQ(field2.Get(i).size(), 1);
+    EXPECT_EQ(field2.Get(i)[0], 'a' + i);
+  }
+}
+
+TEST(RepeatedPtrField, SwapLargeLarge) {
+  RepeatedPtrField<string> field1;
+  RepeatedPtrField<string> field2;
+
+  field1.Add()->assign("foo");
+  field1.Add()->assign("bar");
+  for (int i = 0; i < 16; i++) {
+    *field1.Add() += 'A' + i;
+    *field2.Add() += 'a' + i;
+  }
+  field2.Swap(&field1);
+
+  EXPECT_EQ(field1.size(), 16);
+  for (int i = 0; i < 16; i++) {
+    EXPECT_EQ(field1.Get(i).size(), 1);
+    EXPECT_EQ(field1.Get(i)[0], 'a' + i);
+  }
+  EXPECT_EQ(field2.size(), 18);
+  EXPECT_EQ(field2.Get(0), "foo");
+  EXPECT_EQ(field2.Get(1), "bar");
+  for (int i = 2; i < 18; i++) {
+    EXPECT_EQ(field2.Get(i).size(), 1);
+    EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2);
+  }
+}
+
+static int ReservedSpace(RepeatedPtrField<string>* field) {
+  const string* const* ptr = field->data();
+  do {
+    field->Add();
+  } while (field->data() == ptr);
+
+  return field->size() - 1;
+}
+
+TEST(RepeatedPtrField, ReserveMoreThanDouble) {
+  RepeatedPtrField<string> field;
+  field.Reserve(20);
+
+  EXPECT_EQ(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedPtrField, ReserveLessThanDouble) {
+  RepeatedPtrField<string> field;
+  field.Reserve(20);
+  field.Reserve(30);
+
+  EXPECT_EQ(40, ReservedSpace(&field));
+}
+
+TEST(RepeatedPtrField, ReserveLessThanExisting) {
+  RepeatedPtrField<string> field;
+  field.Reserve(20);
+  const string* const* previous_ptr = field.data();
+  field.Reserve(10);
+
+  EXPECT_EQ(previous_ptr, field.data());
+  EXPECT_EQ(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) {
+  // Check that a bug is fixed:  An earlier implementation of Reserve()
+  // failed to copy pointers to allocated-but-cleared objects, possibly
+  // leading to segfaults.
+  RepeatedPtrField<string> field;
+  string* first = field.Add();
+  field.RemoveLast();
+
+  field.Reserve(20);
+  EXPECT_EQ(first, field.Add());
+}
+
+// Clearing elements is tricky with RepeatedPtrFields since the memory for
+// the elements is retained and reused.
+TEST(RepeatedPtrField, ClearedElements) {
+  RepeatedPtrField<string> field;
+
+  string* original = field.Add();
+  *original = "foo";
+
+  EXPECT_EQ(field.ClearedCount(), 0);
+
+  field.RemoveLast();
+  EXPECT_TRUE(original->empty());
+  EXPECT_EQ(field.ClearedCount(), 1);
+
+  EXPECT_EQ(field.Add(), original);  // Should return same string for reuse.
+
+  EXPECT_EQ(field.ReleaseLast(), original);  // We take ownership.
+  EXPECT_EQ(field.ClearedCount(), 0);
+
+  EXPECT_NE(field.Add(), original);  // Should NOT return the same string.
+  EXPECT_EQ(field.ClearedCount(), 0);
+
+  field.AddAllocated(original);  // Give ownership back.
+  EXPECT_EQ(field.ClearedCount(), 0);
+  EXPECT_EQ(field.Mutable(1), original);
+
+  field.Clear();
+  EXPECT_EQ(field.ClearedCount(), 2);
+  EXPECT_EQ(field.ReleaseCleared(), original);  // Take ownership again.
+  EXPECT_EQ(field.ClearedCount(), 1);
+  EXPECT_NE(field.Add(), original);
+  EXPECT_EQ(field.ClearedCount(), 0);
+  EXPECT_NE(field.Add(), original);
+  EXPECT_EQ(field.ClearedCount(), 0);
+
+  field.AddCleared(original);  // Give ownership back, but as a cleared object.
+  EXPECT_EQ(field.ClearedCount(), 1);
+  EXPECT_EQ(field.Add(), original);
+  EXPECT_EQ(field.ClearedCount(), 0);
+}
+
+TEST(RepeatedPtrField, MergeFrom) {
+  RepeatedPtrField<string> source, destination;
+
+  source.Add()->assign("4");
+  source.Add()->assign("5");
+
+  destination.Add()->assign("1");
+  destination.Add()->assign("2");
+  destination.Add()->assign("3");
+
+  destination.MergeFrom(source);
+
+  ASSERT_EQ(5, destination.size());
+
+  EXPECT_EQ("1", destination.Get(0));
+  EXPECT_EQ("2", destination.Get(1));
+  EXPECT_EQ("3", destination.Get(2));
+  EXPECT_EQ("4", destination.Get(3));
+  EXPECT_EQ("5", destination.Get(4));
+}
+
+TEST(RepeatedPtrField, MutableDataIsMutable) {
+  RepeatedPtrField<string> field;
+  *field.Add() = "1";
+  EXPECT_EQ("1", field.Get(0));
+  // The fact that this line compiles would be enough, but we'll check the
+  // value anyway.
+  string** data = field.mutable_data();
+  **data = "2";
+  EXPECT_EQ("2", field.Get(0));
+}
+
+// ===================================================================
+
+// Iterator tests stolen from net/proto/proto-array_unittest.
+class RepeatedFieldIteratorTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    for (int i = 0; i < 3; ++i) {
+      proto_array_.Add(i);
+    }
+  }
+
+  RepeatedField<int> proto_array_;
+};
+
+TEST_F(RepeatedFieldIteratorTest, Convertible) {
+  RepeatedField<int>::iterator iter = proto_array_.begin();
+  RepeatedField<int>::const_iterator c_iter = iter;
+  EXPECT_EQ(0, *c_iter);
+}
+
+TEST_F(RepeatedFieldIteratorTest, MutableIteration) {
+  RepeatedField<int>::iterator iter = proto_array_.begin();
+  EXPECT_EQ(0, *iter);
+  ++iter;
+  EXPECT_EQ(1, *iter++);
+  EXPECT_EQ(2, *iter);
+  ++iter;
+  EXPECT_TRUE(proto_array_.end() == iter);
+
+  EXPECT_EQ(2, *(proto_array_.end() - 1));
+}
+
+TEST_F(RepeatedFieldIteratorTest, ConstIteration) {
+  const RepeatedField<int>& const_proto_array = proto_array_;
+  RepeatedField<int>::const_iterator iter = const_proto_array.begin();
+  EXPECT_EQ(0, *iter);
+  ++iter;
+  EXPECT_EQ(1, *iter++);
+  EXPECT_EQ(2, *iter);
+  ++iter;
+  EXPECT_TRUE(proto_array_.end() == iter);
+  EXPECT_EQ(2, *(proto_array_.end() - 1));
+}
+
+TEST_F(RepeatedFieldIteratorTest, Mutation) {
+  RepeatedField<int>::iterator iter = proto_array_.begin();
+  *iter = 7;
+  EXPECT_EQ(7, proto_array_.Get(0));
+}
+
+// -------------------------------------------------------------------
+
+class RepeatedPtrFieldIteratorTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    proto_array_.Add()->assign("foo");
+    proto_array_.Add()->assign("bar");
+    proto_array_.Add()->assign("baz");
+  }
+
+  RepeatedPtrField<string> proto_array_;
+};
+
+TEST_F(RepeatedPtrFieldIteratorTest, Convertible) {
+  RepeatedPtrField<string>::iterator iter = proto_array_.begin();
+  RepeatedPtrField<string>::const_iterator c_iter = iter;
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) {
+  RepeatedPtrField<string>::iterator iter = proto_array_.begin();
+  EXPECT_EQ("foo", *iter);
+  ++iter;
+  EXPECT_EQ("bar", *(iter++));
+  EXPECT_EQ("baz", *iter);
+  ++iter;
+  EXPECT_TRUE(proto_array_.end() == iter);
+  EXPECT_EQ("baz", *(--proto_array_.end()));
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) {
+  const RepeatedPtrField<string>& const_proto_array = proto_array_;
+  RepeatedPtrField<string>::const_iterator iter = const_proto_array.begin();
+  EXPECT_EQ("foo", *iter);
+  ++iter;
+  EXPECT_EQ("bar", *(iter++));
+  EXPECT_EQ("baz", *iter);
+  ++iter;
+  EXPECT_TRUE(const_proto_array.end() == iter);
+  EXPECT_EQ("baz", *(--const_proto_array.end()));
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) {
+  RepeatedPtrField<string>::iterator iter = proto_array_.begin();
+  RepeatedPtrField<string>::iterator iter2 = iter;
+  ++iter2;
+  ++iter2;
+  EXPECT_TRUE(iter + 2 == iter2);
+  EXPECT_TRUE(iter == iter2 - 2);
+  EXPECT_EQ("baz", iter[2]);
+  EXPECT_EQ("baz", *(iter + 2));
+  EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, Comparable) {
+  RepeatedPtrField<string>::const_iterator iter = proto_array_.begin();
+  RepeatedPtrField<string>::const_iterator iter2 = iter + 1;
+  EXPECT_TRUE(iter == iter);
+  EXPECT_TRUE(iter != iter2);
+  EXPECT_TRUE(iter < iter2);
+  EXPECT_TRUE(iter <= iter2);
+  EXPECT_TRUE(iter <= iter);
+  EXPECT_TRUE(iter2 > iter);
+  EXPECT_TRUE(iter2 >= iter);
+  EXPECT_TRUE(iter >= iter);
+}
+
+// Uninitialized iterator does not point to any of the RepeatedPtrField.
+// Dereferencing an uninitialized iterator crashes the process.
+TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) {
+  RepeatedPtrField<string>::iterator iter;
+  EXPECT_TRUE(iter != proto_array_.begin());
+  EXPECT_TRUE(iter != proto_array_.begin() + 1);
+  EXPECT_TRUE(iter != proto_array_.begin() + 2);
+  EXPECT_TRUE(iter != proto_array_.begin() + 3);
+  EXPECT_TRUE(iter != proto_array_.end());
+#ifdef GTEST_HAS_DEATH_TEST
+  ASSERT_DEATH(GOOGLE_LOG(INFO) << *iter, "");
+#endif
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) {
+  proto_array_.Clear();
+  proto_array_.Add()->assign("a");
+  proto_array_.Add()->assign("c");
+  proto_array_.Add()->assign("d");
+  proto_array_.Add()->assign("n");
+  proto_array_.Add()->assign("p");
+  proto_array_.Add()->assign("x");
+  proto_array_.Add()->assign("y");
+
+  string v = "f";
+  RepeatedPtrField<string>::const_iterator it =
+      lower_bound(proto_array_.begin(), proto_array_.end(), v);
+  EXPECT_EQ(*it, "n");
+  EXPECT_TRUE(it == proto_array_.begin() + 3);
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, Mutation) {
+  RepeatedPtrField<string>::iterator iter = proto_array_.begin();
+  *iter = "qux";
+  EXPECT_EQ("qux", proto_array_.Get(0));
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/service.cc b/src/google/protobuf/service.cc
new file mode 100644
index 0000000..0c99793
--- /dev/null
+++ b/src/google/protobuf/service.cc
@@ -0,0 +1,32 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/service.h>
+
+namespace google {
+namespace protobuf {
+
+Service::~Service() {}
+RpcChannel::~RpcChannel() {}
+RpcController::~RpcController() {}
+
+}  // namespace protobuf
+
+}  // namespace google
diff --git a/src/google/protobuf/service.h b/src/google/protobuf/service.h
new file mode 100644
index 0000000..f3e78e7
--- /dev/null
+++ b/src/google/protobuf/service.h
@@ -0,0 +1,273 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This module declares the abstract interfaces underlying proto2 RPC
+// services.  These are intented to be independent of any particular RPC
+// implementation, so that proto2 services can be used on top of a variety
+// of implementations.
+//
+//
+// When you use the protocol compiler to compile a service definition, it
+// generates two classes:  An abstract interface for the service (with
+// methods matching the service definition) and a "stub" implementation.
+// A stub is just a type-safe wrapper around an RpcChannel which emulates a
+// local implementation of the service.
+//
+// For example, the service definition:
+//   service MyService {
+//     rpc Foo(MyRequest) returns(MyResponse);
+//   }
+// will generate abstract interface "MyService" and class "MyService::Stub".
+// You could implement a MyService as follows:
+//   class MyServiceImpl : public MyService {
+//    public:
+//     MyServiceImpl() {}
+//     ~MyServiceImpl() {}
+//
+//     // implements MyService ---------------------------------------
+//
+//     void Foo(google::protobuf::RpcController* controller,
+//              const MyRequest* request,
+//              MyResponse* response,
+//              Closure* done) {
+//       // ... read request and fill in response ...
+//       done->Run();
+//     }
+//   };
+// You would then register an instance of MyServiceImpl with your RPC server
+// implementation.  (How to do that depends on the implementation.)
+//
+// To call a remote MyServiceImpl, first you need an RpcChannel connected to it.
+// How to construct a channel depends, again, on your RPC implementation.
+// Here we use a hypothentical "MyRpcChannel" as an example:
+//   MyRpcChannel channel("rpc:hostname:1234/myservice");
+//   MyRpcController controller;
+//   MyServiceImpl::Stub stub(&channel);
+//   FooRequest request;
+//   FooRespnose response;
+//
+//   // ... fill in request ...
+//
+//   stub.Foo(&controller, request, &response, NewCallback(HandleResponse));
+//
+// On Thread-Safety:
+//
+// Different RPC implementations may make different guarantees about what
+// threads they may run callbacks on, and what threads the application is
+// allowed to use to call the RPC system.  Portable software should be ready
+// for callbacks to be called on any thread, but should not try to call the
+// RPC system from any thread except for the ones on which it received the
+// callbacks.  Realistically, though, simple software will probably want to
+// use a single-threaded RPC system while high-end software will want to
+// use multiple threads.  RPC implementations should provide multiple
+// choices.
+
+#ifndef GOOGLE_PROTOBUF_SERVICE_H__
+#define GOOGLE_PROTOBUF_SERVICE_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// Defined in this file.
+class Service;
+class RpcController;
+class RpcChannel;
+
+// Defined in other files.
+class Descriptor;            // descriptor.h
+class ServiceDescriptor;     // descriptor.h
+class MethodDescriptor;      // descriptor.h
+class Message;               // message.h
+
+// Abstract base interface for protocol-buffer-based RPC services.  Services
+// 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).
+class LIBPROTOBUF_EXPORT Service {
+ public:
+  inline Service() {}
+  virtual ~Service();
+
+  // When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second
+  // parameter to the constructor to tell it to delete its RpcChannel when
+  // destroyed.
+  enum ChannelOwnership {
+    STUB_OWNS_CHANNEL,
+    STUB_DOESNT_OWN_CHANNEL
+  };
+
+  // Get the ServiceDescriptor describing this service and its methods.
+  virtual const ServiceDescriptor* GetDescriptor() = 0;
+
+  // Call a method of the service specified by MethodDescriptor.  This is
+  // normally implemented as a simple switch() that calls the standard
+  // definitions of the service's methods.
+  //
+  // Preconditions:
+  // * method->service() == GetDescriptor()
+  // * request and response are of the exact same classes as the objects
+  //   returned by GetRequestPrototype(method) and
+  //   GetResponsePrototype(method).
+  // * After the call has started, the request must not be modified and the
+  //   response must not be accessed at all until "done" is called.
+  // * "controller" is of the correct type for the RPC implementation being
+  //   used by this Service.  For stubs, the "correct type" depends on the
+  //   RpcChannel which the stub is using.  Server-side Service
+  //   implementations are expected to accept whatever type of RpcController
+  //   the server-side RPC implementation uses.
+  //
+  // Postconditions:
+  // * "done" will be called when the method is complete.  This may be
+  //   before CallMethod() returns or it may be at some point in the future.
+  // * If the RPC succeeded, "response" contains the response returned by
+  //   the server.
+  // * If the RPC failed, "response"'s contents are undefined.  The
+  //   RpcController can be queried to determine if an error occurred and
+  //   possibly to get more information about the error.
+  virtual void CallMethod(const MethodDescriptor* method,
+                          RpcController* controller,
+                          const Message* request,
+                          Message* response,
+                          Closure* done) = 0;
+
+  // CallMethod() requires that the request and response passed in are of a
+  // particular subclass of Message.  GetRequestPrototype() and
+  // GetResponsePrototype() get the default instances of these required types.
+  // You can then call Message::New() on these instances to construct mutable
+  // objects which you can then pass to CallMethod().
+  //
+  // Example:
+  //   const MethodDescriptor* method =
+  //     service->GetDescriptor()->FindMethodByName("Foo");
+  //   Message* request  = stub->GetRequestPrototype (method)->New();
+  //   Message* response = stub->GetResponsePrototype(method)->New();
+  //   request->ParseFromString(input);
+  //   service->CallMethod(method, *request, response, callback);
+  virtual const Message& GetRequestPrototype(
+    const MethodDescriptor* method) const = 0;
+  virtual const Message& GetResponsePrototype(
+    const MethodDescriptor* method) const = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Service);
+};
+
+// An RpcController mediates a single method call.  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).
+class LIBPROTOBUF_EXPORT RpcController {
+ public:
+  inline RpcController() {}
+  virtual ~RpcController();
+
+  // Client-side methods ---------------------------------------------
+  // These calls may be made from the client side only.  Their results
+  // are undefined on the server side (may crash).
+
+  // Resets the RpcController to its initial state so that it may be reused in
+  // a new call.  Must not be called while an RPC is in progress.
+  virtual void Reset() = 0;
+
+  // After a call has finished, returns true if the call failed.  The possible
+  // reasons for failure depend on the RPC implementation.  Failed() must not
+  // be called before a call has finished.  If Failed() returns true, the
+  // contents of the response message are undefined.
+  virtual bool Failed() const = 0;
+
+  // If Failed() is true, returns a human-readable description of the error.
+  virtual string ErrorText() const = 0;
+
+  // Advises the RPC system that the caller desires that the RPC call be
+  // canceled.  The RPC system may cancel it immediately, may wait awhile and
+  // then cancel it, or may not even cancel the call at all.  If the call is
+  // canceled, the "done" callback will still be called and the RpcController
+  // will indicate that the call failed at that time.
+  virtual void StartCancel() = 0;
+
+  // Server-side methods ---------------------------------------------
+  // These calls may be made from the server side only.  Their results
+  // are undefined on the client side (may crash).
+
+  // Causes Failed() to return true on the client side.  "reason" will be
+  // incorporated into the message returned by ErrorText().  If you find
+  // you need to return machine-readable information about failures, you
+  // should incorporate it into your response protocol buffer and should
+  // NOT call SetFailed().
+  virtual void SetFailed(const string& reason) = 0;
+
+  // If true, indicates that the client canceled the RPC, so the server may
+  // as well give up on replying to it.  The server should still call the
+  // final "done" callback.
+  virtual bool IsCanceled() const = 0;
+
+  // Asks that the given callback be called when the RPC is canceled.  The
+  // callback will always be called exactly once.  If the RPC completes without
+  // being canceled, the callback will be called after completion.  If the RPC
+  // has already been canceled when NotifyOnCancel() is called, the callback
+  // will be called immediately.
+  //
+  // NotifyOnCancel() must be called no more than once per request.
+  virtual void NotifyOnCancel(Closure* callback) = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcController);
+};
+
+// 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 call an RpcChannel directly, but instead construct a stub Service
+// wrapping it.  Example:
+//   RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234");
+//   MyService* service = new MyService::Stub(channel);
+//   service->MyMethod(request, &response, callback);
+class LIBPROTOBUF_EXPORT RpcChannel {
+ public:
+  inline RpcChannel() {}
+  virtual ~RpcChannel();
+
+  // Call the given method of the remote service.  The signature of this
+  // procedure looks the same as Service::CallMethod(), but the requirements
+  // are less strict in one important way:  the request and response objects
+  // need not be of any specific class as long as their descriptors are
+  // method->input_type() and method->output_type().
+  virtual void CallMethod(const MethodDescriptor* method,
+                          RpcController* controller,
+                          const Message* request,
+                          Message* response,
+                          Closure* done) = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcChannel);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_SERVICE_H__
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc
new file mode 100644
index 0000000..d718284
--- /dev/null
+++ b/src/google/protobuf/stubs/common.cc
@@ -0,0 +1,261 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "config.h"
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN  // We only need minimal includes
+#include <windows.h>
+#elif defined(HAVE_PTHREAD)
+#include <pthread.h>
+#else
+#error "No suitable threading library available."
+#endif
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+void VerifyVersion(int headerVersion,
+                   int minLibraryVersion,
+                   const char* filename) {
+  if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) {
+    // Library is too old for headers.
+    GOOGLE_LOG(FATAL)
+      << "This program requires version " << VersionString(minLibraryVersion)
+      << " of the Protocol Buffer runtime library, but the installed version "
+         "is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ".  Please update "
+         "your library.  If you compiled the program yourself, make sure that "
+         "your headers are from the same version of Protocol Buffers as your "
+         "link-time library.  (Version verification failed in \""
+      << filename << "\".)";
+  }
+  if (headerVersion < kMinHeaderVersionForLibrary) {
+    // Headers are too old for library.
+    GOOGLE_LOG(FATAL)
+      << "This program was compiled against version "
+      << VersionString(headerVersion) << " of the Protocol Buffer runtime "
+         "library, which is not compatible with the installed version ("
+      << VersionString(GOOGLE_PROTOBUF_VERSION) <<  ").  Contact the program "
+         "author for an update.  If you compiled the program yourself, make "
+         "sure that your headers are from the same version of Protocol Buffers "
+         "as your link-time library.  (Version verification failed in \""
+      << filename << "\".)";
+  }
+}
+
+string VersionString(int version) {
+  int major = version / 1000000;
+  int minor = (version / 1000) % 1000;
+  int micro = version % 1000;
+
+  return strings::Substitute("$0.$1.$2", major, minor, micro);
+}
+
+}  // namespace internal
+
+// ===================================================================
+// emulates google3/base/logging.cc
+
+namespace internal {
+
+void DefaultLogHandler(LogLevel level, const char* filename, int line,
+                       const string& message) {
+  static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
+
+  // We use fprintf() instead of cerr because we want this to work at static
+  // initialization time.
+  fprintf(stderr, "libprotobuf %s %s:%d] %s\n",
+          level_names[level], filename, line, message.c_str());
+  fflush(stderr);  // Needed on MSVC.
+}
+
+void NullLogHandler(LogLevel level, const char* filename, int line,
+                    const string& message) {
+  // Nothing.
+}
+
+static LogHandler* log_handler_ = &DefaultLogHandler;
+static int log_silencer_count_ = 0;
+static Mutex log_silencer_count_mutex_;
+
+static string SimpleCtoa(char c) { return string(1, c); }
+
+#undef DECLARE_STREAM_OPERATOR
+#define DECLARE_STREAM_OPERATOR(TYPE, TOSTRING)                     \
+  LogMessage& LogMessage::operator<<(TYPE value) {                  \
+    message_ += TOSTRING(value);                                    \
+    return *this;                                                   \
+  }
+
+DECLARE_STREAM_OPERATOR(const string&, )
+DECLARE_STREAM_OPERATOR(const char*  , )
+DECLARE_STREAM_OPERATOR(char         , SimpleCtoa)
+DECLARE_STREAM_OPERATOR(int          , SimpleItoa)
+DECLARE_STREAM_OPERATOR(uint         , SimpleItoa)
+DECLARE_STREAM_OPERATOR(double       , SimpleDtoa)
+#undef DECLARE_STREAM_OPERATOR
+
+LogMessage::LogMessage(LogLevel level, const char* filename, int line)
+  : level_(level), filename_(filename), line_(line) {}
+LogMessage::~LogMessage() {}
+
+void LogMessage::Finish() {
+  bool suppress = false;
+
+  if (level_ != LOGLEVEL_FATAL) {
+    MutexLock lock(&internal::log_silencer_count_mutex_);
+    suppress = internal::log_silencer_count_ > 0;
+  }
+
+  if (!suppress) {
+    internal::log_handler_(level_, filename_, line_, message_);
+  }
+
+  if (level_ == LOGLEVEL_FATAL) {
+    abort();
+  }
+}
+
+void LogFinisher::operator=(LogMessage& other) {
+  other.Finish();
+}
+
+}  // namespace internal
+
+LogHandler* SetLogHandler(LogHandler* new_func) {
+  LogHandler* old = internal::log_handler_;
+  if (old == &internal::NullLogHandler) {
+    old = NULL;
+  }
+  if (new_func == NULL) {
+    internal::log_handler_ = &internal::NullLogHandler;
+  } else {
+    internal::log_handler_ = new_func;
+  }
+  return old;
+}
+
+LogSilencer::LogSilencer() {
+  MutexLock lock(&internal::log_silencer_count_mutex_);
+  ++internal::log_silencer_count_;
+};
+
+LogSilencer::~LogSilencer() {
+  MutexLock lock(&internal::log_silencer_count_mutex_);
+  --internal::log_silencer_count_;
+};
+
+// ===================================================================
+// emulates google3/base/callback.cc
+
+Closure::~Closure() {}
+
+namespace internal { FunctionClosure0::~FunctionClosure0() {} }
+
+void DoNothing() {}
+
+// ===================================================================
+// emulates google3/base/mutex.cc
+
+#ifdef _WIN32
+
+struct Mutex::Internal {
+  CRITICAL_SECTION mutex;
+#ifndef NDEBUG
+  // Used only to implement AssertHeld().
+  DWORD thread_id;
+#endif
+};
+
+Mutex::Mutex()
+  : mInternal(new Internal) {
+  InitializeCriticalSection(&mInternal->mutex);
+}
+
+Mutex::~Mutex() {
+  DeleteCriticalSection(&mInternal->mutex);
+  delete mInternal;
+}
+
+void Mutex::Lock() {
+  EnterCriticalSection(&mInternal->mutex);
+#ifndef NDEBUG
+  mInternal->thread_id = GetCurrentThreadId();
+#endif
+}
+
+void Mutex::Unlock() {
+#ifndef NDEBUG
+  mInternal->thread_id = 0;
+#endif
+  LeaveCriticalSection(&mInternal->mutex);
+}
+
+void Mutex::AssertHeld() {
+#ifndef NDEBUG
+  GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId());
+#endif
+}
+
+#elif defined(HAVE_PTHREAD)
+
+struct Mutex::Internal {
+  pthread_mutex_t mutex;
+};
+
+Mutex::Mutex()
+  : mInternal(new Internal) {
+  pthread_mutex_init(&mInternal->mutex, NULL);
+}
+
+Mutex::~Mutex() {
+  pthread_mutex_destroy(&mInternal->mutex);
+  delete mInternal;
+}
+
+void Mutex::Lock() {
+  int result = pthread_mutex_lock(&mInternal->mutex);
+  if (result != 0) {
+    GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result);
+  }
+}
+
+void Mutex::Unlock() {
+  int result = pthread_mutex_unlock(&mInternal->mutex);
+  if (result != 0) {
+    GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result);
+  }
+}
+
+void Mutex::AssertHeld() {
+  // pthreads dosn't provide a way to check which thread holds the mutex.
+  // TODO(kenton):  Maybe keep track of locking thread ID like with WIN32?
+}
+
+#endif
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
new file mode 100644
index 0000000..03b176a
--- /dev/null
+++ b/src/google/protobuf/stubs/common.h
@@ -0,0 +1,1061 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda) and others
+//
+// Contains basic types and utilities used by the rest of the library.
+
+#ifndef GOOGLE_PROTOBUF_COMMON_H__
+#define GOOGLE_PROTOBUF_COMMON_H__
+
+#include <assert.h>
+#include <stdlib.h>
+#include <cstddef>
+#include <string>
+#include <string.h>
+#ifndef _MSC_VER
+#include <stdint.h>
+#endif
+
+namespace std {}
+
+namespace google {
+namespace protobuf {
+
+using namespace std;  // Don't do this at home, kids.
+
+#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
+#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)    \
+  TypeName(const TypeName&);                           \
+  void operator=(const TypeName&)
+
+#ifdef _MSC_VER
+  #ifdef LIBPROTOBUF_EXPORTS
+    #define LIBPROTOBUF_EXPORT __declspec(dllexport)
+  #else
+    #define LIBPROTOBUF_EXPORT __declspec(dllimport)
+  #endif
+  #ifdef LIBPROTOC_EXPORTS
+    #define LIBPROTOC_EXPORT   __declspec(dllexport)
+  #else
+    #define LIBPROTOC_EXPORT   __declspec(dllimport)
+  #endif
+#else
+  #define LIBPROTOBUF_EXPORT
+  #define LIBPROTOC_EXPORT
+#endif
+
+namespace internal {
+
+// Some of these constants are macros rather than const ints so that they can
+// be used in #if directives.
+
+// The current version, represented as a single integer to make comparison
+// easier:  major * 10^6 + minor * 10^3 + micro
+#define GOOGLE_PROTOBUF_VERSION 2000001
+
+// The minimum library version which works with the current version of the
+// headers.
+#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2000000
+
+// 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;
+
+// The minimum protoc version which works with the current version of the
+// headers.
+#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2000000
+
+// 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;
+
+// Verifies that the headers and libraries are compatible.  Use the macro
+// below to call this.
+void LIBPROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion,
+                                      const char* filename);
+
+// Converts a numeric version number to a string.
+string LIBPROTOBUF_EXPORT VersionString(int version);
+
+}  // namespace internal
+
+// Place this macro in your main() function (or somewhere before you attempt
+// to use the protobuf library) to verify that the version you link against
+// matches the headers you compiled against.  If a version mismatch is
+// detected, the process will abort.
+#define GOOGLE_PROTOBUF_VERIFY_VERSION                                    \
+  ::google::protobuf::internal::VerifyVersion(                            \
+    GOOGLE_PROTOBUF_VERSION, GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION,         \
+    __FILE__)
+
+// ===================================================================
+// from google3/base/port.h
+
+typedef unsigned int uint;
+
+#ifdef _MSC_VER
+typedef __int8  int8;
+typedef __int16 int16;
+typedef __int32 int32;
+typedef __int64 int64;
+
+typedef unsigned __int8  uint8;
+typedef unsigned __int16 uint16;
+typedef unsigned __int32 uint32;
+typedef unsigned __int64 uint64;
+#else
+typedef int8_t  int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
+
+typedef uint8_t  uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
+#endif
+
+// long long macros to be used because gcc and vc++ use different suffixes,
+// and different size specifiers in format strings
+#undef GOOGLE_LONGLONG
+#undef GOOGLE_ULONGLONG
+#undef GOOGLE_LL_FORMAT
+
+#ifdef _MSC_VER
+#define GOOGLE_LONGLONG(x) x##I64
+#define GOOGLE_ULONGLONG(x) x##UI64
+#define GOOGLE_LL_FORMAT "I64"  // As in printf("%I64d", ...)
+#else
+#define GOOGLE_LONGLONG(x) x##LL
+#define GOOGLE_ULONGLONG(x) x##ULL
+#define GOOGLE_LL_FORMAT "ll"  // As in "%lld". Note that "q" is poor form also.
+#endif
+
+static const int32 kint32max = 0x7FFFFFFF;
+static const int32 kint32min = -kint32min - 1;
+static const int64 kint64max = GOOGLE_LONGLONG(0x7FFFFFFFFFFFFFFF);
+static const int64 kint64min = -kint64max - 1;
+static const uint32 kuint32max = 0xFFFFFFFFu;
+static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
+
+#undef GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+// For functions we want to force inline.
+// Introduced in gcc 3.1.
+#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline))
+#else
+// Other compilers will have to figure it out for themselves.
+#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+#endif
+
+// ===================================================================
+// from google3/base/basictypes.h
+
+// The GOOGLE_ARRAYSIZE(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example.
+//
+// GOOGLE_ARRAYSIZE catches a few type errors.  If you see a compiler error
+//
+//   "warning: division by zero in ..."
+//
+// when using GOOGLE_ARRAYSIZE, you are (wrongfully) giving it a pointer.
+// You should only use GOOGLE_ARRAYSIZE on statically allocated arrays.
+//
+// The following comments are on the implementation details, and can
+// be ignored by the users.
+//
+// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in
+// the array) and sizeof(*(arr)) (the # of bytes in one array
+// element).  If the former is divisible by the latter, perhaps arr is
+// indeed an array, in which case the division result is the # of
+// elements in the array.  Otherwise, arr cannot possibly be an array,
+// and we generate a compiler error to prevent the code from
+// compiling.
+//
+// Since the size of bool is implementation-defined, we need to cast
+// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
+// result has type size_t.
+//
+// This macro is not perfect as it wrongfully accepts certain
+// pointers, namely where the pointer size is divisible by the pointee
+// size.  Since all our code has to go through a 32-bit compiler,
+// where a pointer is 4 bytes, this means all pointers to a type whose
+// size is 3 or greater than 4 will be (righteously) rejected.
+//
+// Kudos to Jorg Brown for this simple and elegant implementation.
+
+#undef GOOGLE_ARRAYSIZE
+#define GOOGLE_ARRAYSIZE(a) \
+  ((sizeof(a) / sizeof(*(a))) / \
+   static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+
+namespace internal {
+
+// Use implicit_cast as a safe version of static_cast or const_cast
+// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
+// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
+// a const pointer to Foo).
+// When you use implicit_cast, the compiler checks that the cast is safe.
+// Such explicit implicit_casts are necessary in surprisingly many
+// situations where C++ demands an exact type match instead of an
+// argument type convertable to a target type.
+//
+// The From type can be inferred, so the preferred syntax for using
+// implicit_cast is the same as for static_cast etc.:
+//
+//   implicit_cast<ToType>(expr)
+//
+// implicit_cast would have been part of the C++ standard library,
+// but the proposal was submitted too late.  It will probably make
+// its way into the language in the future.
+template<typename To, typename From>
+inline To implicit_cast(From const &f) {
+  return f;
+}
+
+// When you upcast (that is, cast a pointer from type Foo to type
+// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
+// always succeed.  When you downcast (that is, cast a pointer from
+// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
+// how do you know the pointer is really of type SubclassOfFoo?  It
+// could be a bare Foo, or of type DifferentSubclassOfFoo.  Thus,
+// when you downcast, you should use this macro.  In debug mode, we
+// use dynamic_cast<> to double-check the downcast is legal (we die
+// if it's not).  In normal mode, we do the efficient static_cast<>
+// instead.  Thus, it's important to test in debug mode to make sure
+// the cast is legal!
+//    This is the only place in the code we should use dynamic_cast<>.
+// In particular, you SHOULDN'T be using dynamic_cast<> in order to
+// do RTTI (eg code like this:
+//    if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
+//    if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
+// You should design the code some other way not to need this.
+
+template<typename To, typename From>     // use like this: down_cast<T*>(foo);
+inline To down_cast(From* f) {                   // so we only accept pointers
+  // Ensures that To is a sub-type of From *.  This test is here only
+  // for compile-time type checking, and has no overhead in an
+  // optimized build at run-time, as it will be optimized away
+  // completely.
+  if (false) {
+    implicit_cast<From*, To>(0);
+  }
+
+  assert(f == NULL || dynamic_cast<To>(f) != NULL);  // RTTI: debug mode only!
+  return static_cast<To>(f);
+}
+
+}  // namespace internal
+
+// We made these internal so that they would show up as such in the docs,
+// but we don't want to stick "internal::" in front of them everywhere.
+using internal::implicit_cast;
+using internal::down_cast;
+
+// The COMPILE_ASSERT macro can be used to verify that a compile time
+// expression is true. For example, you could use it to verify the
+// size of a static array:
+//
+//   COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
+//                  content_type_names_incorrect_size);
+//
+// or to make sure a struct is smaller than a certain size:
+//
+//   COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
+//
+// The second argument to the macro is the name of the variable. If
+// the expression is false, most compilers will issue a warning/error
+// containing the name of the variable.
+
+namespace internal {
+
+template <bool>
+struct CompileAssert {
+};
+
+}  // namespace internal
+
+#undef GOOGLE_COMPILE_ASSERT
+#define GOOGLE_COMPILE_ASSERT(expr, msg) \
+  typedef ::google::protobuf::internal::CompileAssert<(bool(expr))> \
+          msg[bool(expr) ? 1 : -1]
+
+// Implementation details of COMPILE_ASSERT:
+//
+// - COMPILE_ASSERT works by defining an array type that has -1
+//   elements (and thus is invalid) when the expression is false.
+//
+// - The simpler definition
+//
+//     #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
+//
+//   does not work, as gcc supports variable-length arrays whose sizes
+//   are determined at run-time (this is gcc's extension and not part
+//   of the C++ standard).  As a result, gcc fails to reject the
+//   following code with the simple definition:
+//
+//     int foo;
+//     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
+//                               // not a compile-time constant.
+//
+// - By using the type CompileAssert<(bool(expr))>, we ensures that
+//   expr is a compile-time constant.  (Template arguments must be
+//   determined at compile-time.)
+//
+// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
+//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
+//
+//     CompileAssert<bool(expr)>
+//
+//   instead, these compilers will refuse to compile
+//
+//     COMPILE_ASSERT(5 > 0, some_message);
+//
+//   (They seem to think the ">" in "5 > 0" marks the end of the
+//   template argument list.)
+//
+// - The array size is (bool(expr) ? 1 : -1), instead of simply
+//
+//     ((expr) ? 1 : -1).
+//
+//   This is to avoid running into a bug in MS VC 7.1, which
+//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
+
+// ===================================================================
+// from google3/base/scoped_ptr.h
+
+namespace internal {
+
+//  This is an implementation designed to match the anticipated future TR2
+//  implementation of the scoped_ptr class, and its closely-related brethren,
+//  scoped_array, scoped_ptr_malloc, and make_scoped_ptr.
+
+template <class C> class scoped_ptr;
+template <class C> class scoped_array;
+
+// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
+// automatically deletes the pointer it holds (if any).
+// That is, scoped_ptr<T> owns the T object that it points to.
+// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
+//
+// The size of a scoped_ptr is small:
+// sizeof(scoped_ptr<C>) == sizeof(C*)
+template <class C>
+class scoped_ptr {
+ public:
+
+  // The element type
+  typedef C element_type;
+
+  // Constructor.  Defaults to intializing with NULL.
+  // There is no way to create an uninitialized scoped_ptr.
+  // The input parameter must be allocated with new.
+  explicit scoped_ptr(C* p = NULL) : ptr_(p) { }
+
+  // Destructor.  If there is a C object, delete it.
+  // We don't need to test ptr_ == NULL because C++ does that for us.
+  ~scoped_ptr() {
+    enum { type_must_be_complete = sizeof(C) };
+    delete ptr_;
+  }
+
+  // Reset.  Deletes the current owned object, if any.
+  // Then takes ownership of a new object, if given.
+  // this->reset(this->get()) works.
+  void reset(C* p = NULL) {
+    if (p != ptr_) {
+      enum { type_must_be_complete = sizeof(C) };
+      delete ptr_;
+      ptr_ = p;
+    }
+  }
+
+  // Accessors to get the owned object.
+  // operator* and operator-> will assert() if there is no current object.
+  C& operator*() const {
+    assert(ptr_ != NULL);
+    return *ptr_;
+  }
+  C* operator->() const  {
+    assert(ptr_ != NULL);
+    return ptr_;
+  }
+  C* get() const { return ptr_; }
+
+  // Comparison operators.
+  // These return whether two scoped_ptr refer to the same object, not just to
+  // two different but equal objects.
+  bool operator==(C* p) const { return ptr_ == p; }
+  bool operator!=(C* p) const { return ptr_ != p; }
+
+  // Swap two scoped pointers.
+  void swap(scoped_ptr& p2) {
+    C* tmp = ptr_;
+    ptr_ = p2.ptr_;
+    p2.ptr_ = tmp;
+  }
+
+  // Release a pointer.
+  // The return value is the current pointer held by this object.
+  // If this object holds a NULL pointer, the return value is NULL.
+  // After this operation, this object will hold a NULL pointer,
+  // and will not own the object any more.
+  C* release() {
+    C* retVal = ptr_;
+    ptr_ = NULL;
+    return retVal;
+  }
+
+ private:
+  C* ptr_;
+
+  // Forbid comparison of scoped_ptr types.  If C2 != C, it totally doesn't
+  // make sense, and if C2 == C, it still doesn't make sense because you should
+  // never have the same object owned by two different scoped_ptrs.
+  template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
+  template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
+
+  // Disallow evil constructors
+  scoped_ptr(const scoped_ptr&);
+  void operator=(const scoped_ptr&);
+};
+
+// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
+// with new [] and the destructor deletes objects with delete [].
+//
+// As with scoped_ptr<C>, a scoped_array<C> either points to an object
+// or is NULL.  A scoped_array<C> owns the object that it points to.
+//
+// Size: sizeof(scoped_array<C>) == sizeof(C*)
+template <class C>
+class scoped_array {
+ public:
+
+  // The element type
+  typedef C element_type;
+
+  // Constructor.  Defaults to intializing with NULL.
+  // There is no way to create an uninitialized scoped_array.
+  // The input parameter must be allocated with new [].
+  explicit scoped_array(C* p = NULL) : array_(p) { }
+
+  // Destructor.  If there is a C object, delete it.
+  // We don't need to test ptr_ == NULL because C++ does that for us.
+  ~scoped_array() {
+    enum { type_must_be_complete = sizeof(C) };
+    delete[] array_;
+  }
+
+  // Reset.  Deletes the current owned object, if any.
+  // Then takes ownership of a new object, if given.
+  // this->reset(this->get()) works.
+  void reset(C* p = NULL) {
+    if (p != array_) {
+      enum { type_must_be_complete = sizeof(C) };
+      delete[] array_;
+      array_ = p;
+    }
+  }
+
+  // Get one element of the current object.
+  // Will assert() if there is no current object, or index i is negative.
+  C& operator[](std::ptrdiff_t i) const {
+    assert(i >= 0);
+    assert(array_ != NULL);
+    return array_[i];
+  }
+
+  // Get a pointer to the zeroth element of the current object.
+  // If there is no current object, return NULL.
+  C* get() const {
+    return array_;
+  }
+
+  // Comparison operators.
+  // These return whether two scoped_array refer to the same object, not just to
+  // two different but equal objects.
+  bool operator==(C* p) const { return array_ == p; }
+  bool operator!=(C* p) const { return array_ != p; }
+
+  // Swap two scoped arrays.
+  void swap(scoped_array& p2) {
+    C* tmp = array_;
+    array_ = p2.array_;
+    p2.array_ = tmp;
+  }
+
+  // Release an array.
+  // The return value is the current pointer held by this object.
+  // If this object holds a NULL pointer, the return value is NULL.
+  // After this operation, this object will hold a NULL pointer,
+  // and will not own the object any more.
+  C* release() {
+    C* retVal = array_;
+    array_ = NULL;
+    return retVal;
+  }
+
+ private:
+  C* array_;
+
+  // Forbid comparison of different scoped_array types.
+  template <class C2> bool operator==(scoped_array<C2> const& p2) const;
+  template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
+
+  // Disallow evil constructors
+  scoped_array(const scoped_array&);
+  void operator=(const scoped_array&);
+};
+
+}  // namespace internal
+
+// We made these internal so that they would show up as such in the docs,
+// but we don't want to stick "internal::" in front of them everywhere.
+using internal::scoped_ptr;
+using internal::scoped_array;
+
+// ===================================================================
+// emulates google3/base/logging.h
+
+enum LogLevel {
+  LOGLEVEL_INFO,     // Informational.  This is never actually used by
+                     // libprotobuf.
+  LOGLEVEL_WARNING,  // Warns about issues that, although not technically a
+                     // problem now, could cause problems in the future.  For
+                     // example, a // warning will be printed when parsing a
+                     // message that is near the message size limit.
+  LOGLEVEL_ERROR,    // An error occurred which should never happen during
+                     // normal use.
+  LOGLEVEL_FATAL,    // An error occurred from which the library cannot
+                     // recover.  This usually indicates a programming error
+                     // in the code which calls the library, especially when
+                     // compiled in debug mode.
+
+#ifdef NDEBUG
+  LOGLEVEL_DFATAL = LOGLEVEL_ERROR
+#else
+  LOGLEVEL_DFATAL = LOGLEVEL_FATAL
+#endif
+};
+
+namespace internal {
+
+class LogFinisher;
+
+class LIBPROTOBUF_EXPORT LogMessage {
+ public:
+  LogMessage(LogLevel level, const char* filename, int line);
+  ~LogMessage();
+
+  LogMessage& operator<<(const string& value);
+  LogMessage& operator<<(const char* value);
+  LogMessage& operator<<(char value);
+  LogMessage& operator<<(int value);
+  LogMessage& operator<<(uint value);
+  LogMessage& operator<<(double value);
+
+ private:
+  friend class LogFinisher;
+  void Finish();
+
+  LogLevel level_;
+  const char* filename_;
+  int line_;
+  string message_;
+};
+
+// Used to make the entire "LOG(BLAH) << etc." expression have a void return
+// type and print a newline after each message.
+class LIBPROTOBUF_EXPORT LogFinisher {
+ public:
+  void operator=(LogMessage& other);
+};
+
+}  // namespace internal
+
+// Undef everything in case we're being mixed with some other Google library
+// which already defined them itself.  Presumably all Google libraries will
+// support the same syntax for these so it should not be a big deal if they
+// end up using our definitions instead.
+#undef GOOGLE_LOG
+#undef GOOGLE_LOG_IF
+
+#undef GOOGLE_CHECK
+#undef GOOGLE_CHECK_EQ
+#undef GOOGLE_CHECK_NE
+#undef GOOGLE_CHECK_LT
+#undef GOOGLE_CHECK_LE
+#undef GOOGLE_CHECK_GT
+#undef GOOGLE_CHECK_GE
+
+#undef GOOGLE_DLOG
+#undef GOOGLE_DCHECK
+#undef GOOGLE_DCHECK_EQ
+#undef GOOGLE_DCHECK_NE
+#undef GOOGLE_DCHECK_LT
+#undef GOOGLE_DCHECK_LE
+#undef GOOGLE_DCHECK_GT
+#undef GOOGLE_DCHECK_GE
+
+#define GOOGLE_LOG(LEVEL)                                                 \
+  ::google::protobuf::internal::LogFinisher() =                           \
+    ::google::protobuf::internal::LogMessage(                             \
+      ::google::protobuf::LOGLEVEL_##LEVEL, __FILE__, __LINE__)
+#define GOOGLE_LOG_IF(LEVEL, CONDITION) \
+  !(CONDITION) ? (void)0 : GOOGLE_LOG(LEVEL)
+
+#define GOOGLE_CHECK(EXPRESSION) \
+  GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": "
+#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK(A == B)
+#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK(A != B)
+#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK(A <  B)
+#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK(A <= B)
+#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK(A >  B)
+#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK(A >= B)
+
+#ifdef NDEBUG
+
+#define GOOGLE_DLOG GOOGLE_LOG_IF(false, INFO)
+
+#define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION)
+#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK(A == B)
+#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK(A != B)
+#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK(A <  B)
+#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK(A <= B)
+#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK(A >  B)
+#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK(A >= B)
+
+#else  // NDEBUG
+
+#define GOOGLE_DLOG GOOGLE_LOG
+
+#define GOOGLE_DCHECK    GOOGLE_CHECK
+#define GOOGLE_DCHECK_EQ GOOGLE_CHECK_EQ
+#define GOOGLE_DCHECK_NE GOOGLE_CHECK_NE
+#define GOOGLE_DCHECK_LT GOOGLE_CHECK_LT
+#define GOOGLE_DCHECK_LE GOOGLE_CHECK_LE
+#define GOOGLE_DCHECK_GT GOOGLE_CHECK_GT
+#define GOOGLE_DCHECK_GE GOOGLE_CHECK_GE
+
+#endif  // !NDEBUG
+
+typedef void LogHandler(LogLevel level, const char* filename, int line,
+                        const string& message);
+
+// The protobuf library sometimes writes warning and error messages to
+// stderr.  These messages are primarily useful for developers, but may
+// also help end users figure out a problem.  If you would prefer that
+// these messages be sent somewhere other than stderr, call SetLogHandler()
+// to set your own handler.  This returns the old handler.  Set the handler
+// to NULL to ignore log messages (but see also LogSilencer, below).
+//
+// Obviously, SetLogHandler is not thread-safe.  You should only call it
+// at initialization time, and probably not from library code.  If you
+// simply want to suppress log messages temporarily (e.g. because you
+// have some code that tends to trigger them frequently and you know
+// the warnings are not important to you), use the LogSilencer class
+// below.
+LIBPROTOBUF_EXPORT LogHandler* SetLogHandler(LogHandler* new_func);
+
+// Create a LogSilencer if you want to temporarily suppress all log
+// messages.  As long as any LogSilencer objects exist, non-fatal
+// log messages will be discarded (the current LogHandler will *not*
+// be called).  Constructing a LogSilencer is thread-safe.  You may
+// accidentally suppress log messages occurring in another thread, but
+// since messages are generally for debugging purposes only, this isn't
+// a big deal.  If you want to intercept log messages, use SetLogHandler().
+class LIBPROTOBUF_EXPORT LogSilencer {
+ public:
+  LogSilencer();
+  ~LogSilencer();
+};
+
+// ===================================================================
+// emulates google3/base/callback.h
+
+// Abstract interface for a callback.  When calling an RPC, you must provide
+// a Closure to call when the procedure completes.  See the Service interface
+// in service.h.
+//
+// To automatically construct a Closure which calls a particular function or
+// method with a particular set of parameters, use the NewCallback() function.
+// Example:
+//   void FooDone(const FooResponse* response) {
+//     ...
+//   }
+//
+//   void CallFoo() {
+//     ...
+//     // When done, call FooDone() and pass it a pointer to the response.
+//     Closure* callback = NewCallback(&FooDone, response);
+//     // Make the call.
+//     service->Foo(controller, request, response, callback);
+//   }
+//
+// Example that calls a method:
+//   class Handler {
+//    public:
+//     ...
+//
+//     void FooDone(const FooResponse* response) {
+//       ...
+//     }
+//
+//     void CallFoo() {
+//       ...
+//       // When done, call FooDone() and pass it a pointer to the response.
+//       Closure* callback = NewCallback(this, &Handler::FooDone, response);
+//       // Make the call.
+//       service->Foo(controller, request, response, callback);
+//     }
+//   };
+//
+// Currently NewCallback() supports binding zero, one, or two arguments.
+//
+// Callbacks created with NewCallback() automatically delete themselves when
+// executed.  They should be used when a callback is to be called exactly
+// once (usually the case with RPC callbacks).  If a callback may be called
+// a different number of times (including zero), create it with
+// NewPermanentCallback() instead.  You are then responsible for deleting the
+// callback (using the "delete" keyword as normal).
+//
+// Note that NewCallback() is a bit touchy regarding argument types.  Generally,
+// the values you provide for the parameter bindings must exactly match the
+// types accepted by the callback function.  For example:
+//   void Foo(string s);
+//   NewCallback(&Foo, "foo");          // WON'T WORK:  const char* != string
+//   NewCallback(&Foo, string("foo"));  // WORKS
+// Also note that the arguments cannot be references:
+//   void Foo(const string& s);
+//   string my_str;
+//   NewCallback(&Foo, my_str);  // WON'T WORK:  Can't use referecnes.
+// However, correctly-typed pointers will work just fine.
+class LIBPROTOBUF_EXPORT Closure {
+ public:
+  Closure() {}
+  virtual ~Closure();
+
+  virtual void Run() = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure);
+};
+
+namespace internal {
+
+class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure {
+ public:
+  typedef void (*FunctionType)();
+
+  FunctionClosure0(FunctionType function, bool self_deleting)
+    : function_(function), self_deleting_(self_deleting) {}
+  ~FunctionClosure0();
+
+  void Run() {
+    function_();
+    if (self_deleting_) delete this;
+  }
+
+ private:
+  FunctionType function_;
+  bool self_deleting_;
+};
+
+template <typename Class>
+class MethodClosure0 : public Closure {
+ public:
+  typedef void (Class::*MethodType)();
+
+  MethodClosure0(Class* object, MethodType method, bool self_deleting)
+    : object_(object), method_(method), self_deleting_(self_deleting) {}
+  ~MethodClosure0() {}
+
+  void Run() {
+    (object_->*method_)();
+    if (self_deleting_) delete this;
+  }
+
+ private:
+  Class* object_;
+  MethodType method_;
+  bool self_deleting_;
+};
+
+template <typename Arg1>
+class FunctionClosure1 : public Closure {
+ public:
+  typedef void (*FunctionType)(Arg1 arg1);
+
+  FunctionClosure1(FunctionType function, bool self_deleting,
+                   Arg1 arg1)
+    : function_(function), self_deleting_(self_deleting),
+      arg1_(arg1) {}
+  ~FunctionClosure1() {}
+
+  void Run() {
+    function_(arg1_);
+    if (self_deleting_) delete this;
+  }
+
+ private:
+  FunctionType function_;
+  bool self_deleting_;
+  Arg1 arg1_;
+};
+
+template <typename Class, typename Arg1>
+class MethodClosure1 : public Closure {
+ public:
+  typedef void (Class::*MethodType)(Arg1 arg1);
+
+  MethodClosure1(Class* object, MethodType method, bool self_deleting,
+                 Arg1 arg1)
+    : object_(object), method_(method), self_deleting_(self_deleting),
+      arg1_(arg1) {}
+  ~MethodClosure1() {}
+
+  void Run() {
+    (object_->*method_)(arg1_);
+    if (self_deleting_) delete this;
+  }
+
+ private:
+  Class* object_;
+  MethodType method_;
+  bool self_deleting_;
+  Arg1 arg1_;
+};
+
+template <typename Arg1, typename Arg2>
+class FunctionClosure2 : public Closure {
+ public:
+  typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2);
+
+  FunctionClosure2(FunctionType function, bool self_deleting,
+                   Arg1 arg1, Arg2 arg2)
+    : function_(function), self_deleting_(self_deleting),
+      arg1_(arg1), arg2_(arg2) {}
+  ~FunctionClosure2() {}
+
+  void Run() {
+    function_(arg1_, arg2_);
+    if (self_deleting_) delete this;
+  }
+
+ private:
+  FunctionType function_;
+  bool self_deleting_;
+  Arg1 arg1_;
+  Arg2 arg2_;
+};
+
+template <typename Class, typename Arg1, typename Arg2>
+class MethodClosure2 : public Closure {
+ public:
+  typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2);
+
+  MethodClosure2(Class* object, MethodType method, bool self_deleting,
+                 Arg1 arg1, Arg2 arg2)
+    : object_(object), method_(method), self_deleting_(self_deleting),
+      arg1_(arg1), arg2_(arg2) {}
+  ~MethodClosure2() {}
+
+  void Run() {
+    (object_->*method_)(arg1_, arg2_);
+    if (self_deleting_) delete this;
+  }
+
+ private:
+  Class* object_;
+  MethodType method_;
+  bool self_deleting_;
+  Arg1 arg1_;
+  Arg2 arg2_;
+};
+
+}  // namespace internal
+
+// See Closure.
+inline Closure* NewCallback(void (*function)()) {
+  return new internal::FunctionClosure0(function, true);
+}
+
+// See Closure.
+inline Closure* NewPermanentCallback(void (*function)()) {
+  return new internal::FunctionClosure0(function, false);
+}
+
+// See Closure.
+template <typename Class>
+inline Closure* NewCallback(Class* object, void (Class::*method)()) {
+  return new internal::MethodClosure0<Class>(object, method, true);
+}
+
+// See Closure.
+template <typename Class>
+inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) {
+  return new internal::MethodClosure0<Class>(object, method, false);
+}
+
+// See Closure.
+template <typename Arg1>
+inline Closure* NewCallback(void (*function)(Arg1),
+                            Arg1 arg1) {
+  return new internal::FunctionClosure1<Arg1>(function, true, arg1);
+}
+
+// See Closure.
+template <typename Arg1>
+inline Closure* NewPermanentCallback(void (*function)(Arg1),
+                                     Arg1 arg1) {
+  return new internal::FunctionClosure1<Arg1>(function, false, arg1);
+}
+
+// See Closure.
+template <typename Class, typename Arg1>
+inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1),
+                            Arg1 arg1) {
+  return new internal::MethodClosure1<Class, Arg1>(object, method, true, arg1);
+}
+
+// See Closure.
+template <typename Class, typename Arg1>
+inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1),
+                                     Arg1 arg1) {
+  return new internal::MethodClosure1<Class, Arg1>(object, method, false, arg1);
+}
+
+// See Closure.
+template <typename Arg1, typename Arg2>
+inline Closure* NewCallback(void (*function)(Arg1, Arg2),
+                            Arg1 arg1, Arg2 arg2) {
+  return new internal::FunctionClosure2<Arg1, Arg2>(
+    function, true, arg1, arg2);
+}
+
+// See Closure.
+template <typename Arg1, typename Arg2>
+inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2),
+                                     Arg1 arg1, Arg2 arg2) {
+  return new internal::FunctionClosure2<Arg1, Arg2>(
+    function, false, arg1, arg2);
+}
+
+// See Closure.
+template <typename Class, typename Arg1, typename Arg2>
+inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2),
+                            Arg1 arg1, Arg2 arg2) {
+  return new internal::MethodClosure2<Class, Arg1, Arg2>(
+    object, method, true, arg1, arg2);
+}
+
+// See Closure.
+template <typename Class, typename Arg1, typename Arg2>
+inline Closure* NewPermanentCallback(
+    Class* object, void (Class::*method)(Arg1, Arg2),
+    Arg1 arg1, Arg2 arg2) {
+  return new internal::MethodClosure2<Class, Arg1, Arg2>(
+    object, method, false, arg1, arg2);
+}
+
+// A function which does nothing.  Useful for creating no-op callbacks, e.g.:
+//   Closure* nothing = NewCallback(&DoNothing);
+void LIBPROTOBUF_EXPORT DoNothing();
+
+// ===================================================================
+// emulates google3/base/mutex.h
+
+namespace internal {
+
+// A Mutex is a non-reentrant (aka non-recursive) mutex.  At most one thread T
+// may hold a mutex at a given time.  If T attempts to Lock() the same Mutex
+// while holding it, T will deadlock.
+class LIBPROTOBUF_EXPORT Mutex {
+ public:
+  // Create a Mutex that is not held by anybody.
+  Mutex();
+
+  // Destructor
+  ~Mutex();
+
+  // Block if necessary until this Mutex is free, then acquire it exclusively.
+  void Lock();
+
+  // Release this Mutex.  Caller must hold it exclusively.
+  void Unlock();
+
+  // Crash if this Mutex is not held exclusively by this thread.
+  // May fail to crash when it should; will never crash when it should not.
+  void AssertHeld();
+
+ private:
+  struct Internal;
+  Internal* mInternal;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex);
+};
+
+// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
+class LIBPROTOBUF_EXPORT MutexLock {
+ public:
+  explicit MutexLock(Mutex *mu) : mu_(mu) { this->mu_->Lock(); }
+  ~MutexLock() { this->mu_->Unlock(); }
+ private:
+  Mutex *const mu_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock);
+};
+
+// MutexLockMaybe is like MutexLock, but is a no-op when mu is NULL.
+class LIBPROTOBUF_EXPORT MutexLockMaybe {
+ public:
+  explicit MutexLockMaybe(Mutex *mu) :
+    mu_(mu) { if (this->mu_ != NULL) { this->mu_->Lock(); } }
+  ~MutexLockMaybe() { if (this->mu_ != NULL) { this->mu_->Unlock(); } }
+ private:
+  Mutex *const mu_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe);
+};
+
+}  // namespace internal
+
+// We made these internal so that they would show up as such in the docs,
+// but we don't want to stick "internal::" in front of them everywhere.
+using internal::Mutex;
+using internal::MutexLock;
+using internal::MutexLockMaybe;
+
+// ===================================================================
+// from google3/base/type_traits.h
+
+namespace internal {
+
+// Specified by TR1 [4.7.4] Pointer modifications.
+template<typename T> struct remove_pointer { typedef T type; };
+template<typename T> struct remove_pointer<T*> { typedef T type; };
+template<typename T> struct remove_pointer<T* const> { typedef T type; };
+template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
+template<typename T> struct remove_pointer<T* const volatile> {
+  typedef T type; };
+
+}  // namespace internal
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_COMMON_H__
diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc
new file mode 100644
index 0000000..f12422b
--- /dev/null
+++ b/src/google/protobuf/stubs/common_unittest.cc
@@ -0,0 +1,319 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+#include "config.h"
+
+namespace google {
+namespace protobuf {
+namespace {
+
+// TODO(kenton):  More tests.
+
+#ifdef PACKAGE_VERSION  // only defined when using automake, not MSVC
+
+TEST(VersionTest, VersionMatchesConfig) {
+  // Verify that the version string specified in config.h matches the one
+  // in common.h.  The config.h version is a string which may have a suffix
+  // like "beta", so we remove that.
+  string version = PACKAGE_VERSION;
+  int pos = version.size();
+  while (pos > 0 && !ascii_isdigit(version[pos-1])) {
+    --pos;
+  }
+  version.erase(pos);
+
+  EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION));
+}
+
+#endif  // PACKAGE_VERSION
+
+vector<string> captured_messages_;
+
+void CaptureLog(LogLevel level, const char* filename, int line,
+                const string& message) {
+  captured_messages_.push_back(
+    strings::Substitute("$0 $1:$2: $3",
+      implicit_cast<int>(level), filename, line, message));
+}
+
+TEST(LoggingTest, DefaultLogging) {
+  CaptureTestStderr();
+  int line = __LINE__;
+  GOOGLE_LOG(INFO   ) << "A message.";
+  GOOGLE_LOG(WARNING) << "A warning.";
+  GOOGLE_LOG(ERROR  ) << "An error.";
+
+  string text = GetCapturedTestStderr();
+  EXPECT_EQ(
+    "libprotobuf INFO "__FILE__":" + SimpleItoa(line + 1) + "] A message.\n"
+    "libprotobuf WARNING "__FILE__":" + SimpleItoa(line + 2) + "] A warning.\n"
+    "libprotobuf ERROR "__FILE__":" + SimpleItoa(line + 3) + "] An error.\n",
+    text);
+}
+
+TEST(LoggingTest, NullLogging) {
+  LogHandler* old_handler = SetLogHandler(NULL);
+
+  CaptureTestStderr();
+  GOOGLE_LOG(INFO   ) << "A message.";
+  GOOGLE_LOG(WARNING) << "A warning.";
+  GOOGLE_LOG(ERROR  ) << "An error.";
+
+  EXPECT_TRUE(SetLogHandler(old_handler) == NULL);
+
+  string text = GetCapturedTestStderr();
+  EXPECT_EQ("", text);
+}
+
+TEST(LoggingTest, CaptureLogging) {
+  captured_messages_.clear();
+
+  LogHandler* old_handler = SetLogHandler(&CaptureLog);
+
+  int start_line = __LINE__;
+  GOOGLE_LOG(ERROR) << "An error.";
+  GOOGLE_LOG(WARNING) << "A warning.";
+
+  EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
+
+  ASSERT_EQ(2, captured_messages_.size());
+  EXPECT_EQ(
+    "2 "__FILE__":" + SimpleItoa(start_line + 1) + ": An error.",
+    captured_messages_[0]);
+  EXPECT_EQ(
+    "1 "__FILE__":" + SimpleItoa(start_line + 2) + ": A warning.",
+    captured_messages_[1]);
+}
+
+TEST(LoggingTest, SilenceLogging) {
+  captured_messages_.clear();
+
+  LogHandler* old_handler = SetLogHandler(&CaptureLog);
+
+  int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1";
+  LogSilencer* silencer1 = new LogSilencer;
+  GOOGLE_LOG(INFO) << "Not visible.";
+  LogSilencer* silencer2 = new LogSilencer;
+  GOOGLE_LOG(INFO) << "Not visible.";
+  delete silencer1;
+  GOOGLE_LOG(INFO) << "Not visible.";
+  delete silencer2;
+  int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2";
+
+  EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
+
+  ASSERT_EQ(2, captured_messages_.size());
+  EXPECT_EQ(
+    "0 "__FILE__":" + SimpleItoa(line1) + ": Visible1",
+    captured_messages_[0]);
+  EXPECT_EQ(
+    "0 "__FILE__":" + SimpleItoa(line2) + ": Visible2",
+    captured_messages_[1]);
+}
+
+class ClosureTest : public testing::Test {
+ public:
+  void SetA123Method()   { a_ = 123; }
+  static void SetA123Function() { current_instance_->a_ = 123; }
+
+  void SetAMethod(int a)         { a_ = a; }
+  void SetCMethod(string c)      { c_ = c; }
+
+  static void SetAFunction(int a)         { current_instance_->a_ = a; }
+  static void SetCFunction(string c)      { current_instance_->c_ = c; }
+
+  void SetABMethod(int a, const char* b)  { a_ = a; b_ = b; }
+  static void SetABFunction(int a, const char* b) {
+    current_instance_->a_ = a;
+    current_instance_->b_ = b;
+  }
+
+  virtual void SetUp() {
+    current_instance_ = this;
+    a_ = 0;
+    b_ = NULL;
+    c_.clear();
+  }
+
+  int a_;
+  const char* b_;
+  string c_;
+
+  static ClosureTest* current_instance_;
+};
+
+ClosureTest* ClosureTest::current_instance_ = NULL;
+
+TEST_F(ClosureTest, TestClosureFunction0) {
+  Closure* closure = NewCallback(&SetA123Function);
+  EXPECT_NE(123, a_);
+  closure->Run();
+  EXPECT_EQ(123, a_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod0) {
+  Closure* closure = NewCallback(current_instance_,
+                                 &ClosureTest::SetA123Method);
+  EXPECT_NE(123, a_);
+  closure->Run();
+  EXPECT_EQ(123, a_);
+}
+
+TEST_F(ClosureTest, TestClosureFunction1) {
+  Closure* closure = NewCallback(&SetAFunction, 456);
+  EXPECT_NE(456, a_);
+  closure->Run();
+  EXPECT_EQ(456, a_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod1) {
+  Closure* closure = NewCallback(current_instance_,
+                                 &ClosureTest::SetAMethod, 456);
+  EXPECT_NE(456, a_);
+  closure->Run();
+  EXPECT_EQ(456, a_);
+}
+
+TEST_F(ClosureTest, TestClosureFunction1String) {
+  Closure* closure = NewCallback(&SetCFunction, string("test"));
+  EXPECT_NE("test", c_);
+  closure->Run();
+  EXPECT_EQ("test", c_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod1String) {
+  Closure* closure = NewCallback(current_instance_,
+                                 &ClosureTest::SetCMethod, string("test"));
+  EXPECT_NE("test", c_);
+  closure->Run();
+  EXPECT_EQ("test", c_);
+}
+
+TEST_F(ClosureTest, TestClosureFunction2) {
+  const char* cstr = "hello";
+  Closure* closure = NewCallback(&SetABFunction, 789, cstr);
+  EXPECT_NE(789, a_);
+  EXPECT_NE(cstr, b_);
+  closure->Run();
+  EXPECT_EQ(789, a_);
+  EXPECT_EQ(cstr, b_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod2) {
+  const char* cstr = "hello";
+  Closure* closure = NewCallback(current_instance_,
+                                 &ClosureTest::SetABMethod, 789, cstr);
+  EXPECT_NE(789, a_);
+  EXPECT_NE(cstr, b_);
+  closure->Run();
+  EXPECT_EQ(789, a_);
+  EXPECT_EQ(cstr, b_);
+}
+
+// Repeat all of the above with NewPermanentCallback()
+
+TEST_F(ClosureTest, TestPermanentClosureFunction0) {
+  Closure* closure = NewPermanentCallback(&SetA123Function);
+  EXPECT_NE(123, a_);
+  closure->Run();
+  EXPECT_EQ(123, a_);
+  a_ = 0;
+  closure->Run();
+  EXPECT_EQ(123, a_);
+  delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureMethod0) {
+  Closure* closure = NewPermanentCallback(current_instance_,
+                                          &ClosureTest::SetA123Method);
+  EXPECT_NE(123, a_);
+  closure->Run();
+  EXPECT_EQ(123, a_);
+  a_ = 0;
+  closure->Run();
+  EXPECT_EQ(123, a_);
+  delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureFunction1) {
+  Closure* closure = NewPermanentCallback(&SetAFunction, 456);
+  EXPECT_NE(456, a_);
+  closure->Run();
+  EXPECT_EQ(456, a_);
+  a_ = 0;
+  closure->Run();
+  EXPECT_EQ(456, a_);
+  delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureMethod1) {
+  Closure* closure = NewPermanentCallback(current_instance_,
+                                          &ClosureTest::SetAMethod, 456);
+  EXPECT_NE(456, a_);
+  closure->Run();
+  EXPECT_EQ(456, a_);
+  a_ = 0;
+  closure->Run();
+  EXPECT_EQ(456, a_);
+  delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureFunction2) {
+  const char* cstr = "hello";
+  Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr);
+  EXPECT_NE(789, a_);
+  EXPECT_NE(cstr, b_);
+  closure->Run();
+  EXPECT_EQ(789, a_);
+  EXPECT_EQ(cstr, b_);
+  a_ = 0;
+  b_ = NULL;
+  closure->Run();
+  EXPECT_EQ(789, a_);
+  EXPECT_EQ(cstr, b_);
+  delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureMethod2) {
+  const char* cstr = "hello";
+  Closure* closure = NewPermanentCallback(current_instance_,
+                                          &ClosureTest::SetABMethod, 789, cstr);
+  EXPECT_NE(789, a_);
+  EXPECT_NE(cstr, b_);
+  closure->Run();
+  EXPECT_EQ(789, a_);
+  EXPECT_EQ(cstr, b_);
+  a_ = 0;
+  b_ = NULL;
+  closure->Run();
+  EXPECT_EQ(789, a_);
+  EXPECT_EQ(cstr, b_);
+  delete closure;
+}
+
+}  // anonymous namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/stubs/hash.cc b/src/google/protobuf/stubs/hash.cc
new file mode 100644
index 0000000..43fb9d7
--- /dev/null
+++ b/src/google/protobuf/stubs/hash.cc
@@ -0,0 +1,27 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/hash.h>
+
+namespace google {
+namespace protobuf {
+
+// Nothing needed here right now.
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
new file mode 100644
index 0000000..a62b3f6
--- /dev/null
+++ b/src/google/protobuf/stubs/hash.h
@@ -0,0 +1,123 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// Deals with the fact that hash_map is not defined everywhere.
+
+#ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__
+#define GOOGLE_PROTOBUF_STUBS_HASH_H__
+
+#include <string.h>
+#include <google/protobuf/stubs/common.h>
+#include "config.h"
+
+#if defined(HAVE_HASH_MAP) && defined(HAVE_HASH_SET)
+#include HASH_MAP_H
+#include HASH_SET_H
+#else
+// TODO(kenton):  Deal with non-existence of hash_map somehow.  Maybe emulate
+//   it with map?
+#error "Your STL implementation lacks hash_map and/or hash_set."
+#endif
+
+namespace google {
+namespace protobuf {
+
+#ifdef _MSC_VER
+
+template <typename Key>
+struct hash : public HASH_NAMESPACE::hash_compare<Key> {
+};
+
+// MSVC's hash_compare<const char*> hashes based on the string contents but
+// compares based on the string pointer.  WTF?
+class CstringLess {
+ public:
+  inline bool operator()(const char* a, const char* b) const {
+    return strcmp(a, b) < 0;
+  }
+};
+
+template <>
+struct hash<const char*>
+  : public HASH_NAMESPACE::hash_compare<const char*, CstringLess> {
+};
+
+template <typename Key, typename Data,
+          typename HashFcn = hash<Key>,
+          typename EqualKey = int >
+class hash_map : public HASH_NAMESPACE::hash_map<
+    Key, Data, HashFcn> {
+};
+
+template <typename Key,
+          typename HashFcn = hash<Key>,
+          typename EqualKey = int >
+class hash_set : public HASH_NAMESPACE::hash_set<
+    Key, HashFcn> {
+};
+
+#else
+
+template <typename Key>
+struct hash : public HASH_NAMESPACE::hash<Key> {
+};
+
+template <typename Key>
+struct hash<const Key*> {
+  inline size_t operator()(const Key* key) const {
+    return reinterpret_cast<size_t>(key);
+  }
+};
+
+template <>
+struct hash<const char*> : public HASH_NAMESPACE::hash<const char*> {
+};
+
+template <typename Key, typename Data,
+          typename HashFcn = hash<Key>,
+          typename EqualKey = std::equal_to<Key> >
+class hash_map : public HASH_NAMESPACE::hash_map<
+    Key, Data, HashFcn, EqualKey> {
+};
+
+template <typename Key,
+          typename HashFcn = hash<Key>,
+          typename EqualKey = std::equal_to<Key> >
+class hash_set : public HASH_NAMESPACE::hash_set<
+    Key, HashFcn, EqualKey> {
+};
+
+#endif
+
+template <>
+struct hash<string> {
+  inline size_t operator()(const string& key) const {
+    return hash<const char*>()(key.c_str());
+  }
+
+  static const size_t bucket_size = 4;
+  static const size_t min_buckets = 8;
+  inline size_t operator()(const string& a, const string& b) const {
+    return a < b;
+  }
+};
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_HASH_H__
diff --git a/src/google/protobuf/stubs/map-util.cc b/src/google/protobuf/stubs/map-util.cc
new file mode 100644
index 0000000..af05af3
--- /dev/null
+++ b/src/google/protobuf/stubs/map-util.cc
@@ -0,0 +1,28 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// from google3/util/gtl/map-util.cc
+// Author: Anton Carver
+
+#include <google/protobuf/stubs/map-util.h>
+
+namespace google {
+namespace protobuf {
+
+// Template module.  Nothing to see here.
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/stubs/map-util.h b/src/google/protobuf/stubs/map-util.h
new file mode 100644
index 0000000..ee8073f
--- /dev/null
+++ b/src/google/protobuf/stubs/map-util.h
@@ -0,0 +1,90 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// from google3/util/gtl/map-util.h
+// Author: Anton Carver
+
+#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
+#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// Perform a lookup in a map or hash_map.
+// If the key is present a const pointer to the associated value is returned,
+// otherwise a NULL pointer is returned.
+template <class Collection>
+const typename Collection::value_type::second_type*
+FindOrNull(const Collection& collection,
+           const typename Collection::value_type::first_type& key) {
+  typename Collection::const_iterator it = collection.find(key);
+  if (it == collection.end()) {
+    return 0;
+  }
+  return &it->second;
+}
+
+// Perform a lookup in a map or hash_map whose values are pointers.
+// If the key is present a const pointer to the associated value is returned,
+// otherwise a NULL pointer is returned.
+// This function does not distinguish between a missing key and a key mapped
+// to a NULL value.
+template <class Collection>
+const typename Collection::value_type::second_type
+FindPtrOrNull(const Collection& collection,
+              const typename Collection::value_type::first_type& key) {
+  typename Collection::const_iterator it = collection.find(key);
+  if (it == collection.end()) {
+    return 0;
+  }
+  return it->second;
+}
+
+// Change the value associated with a particular key in a map or hash_map.
+// If the key is not present in the map the key and value are inserted,
+// otherwise the value is updated to be a copy of the value provided.
+// True indicates that an insert took place, false indicates an update.
+template <class Collection, class Key, class Value>
+bool InsertOrUpdate(Collection * const collection,
+                   const Key& key, const Value& value) {
+  pair<typename Collection::iterator, bool> ret =
+    collection->insert(typename Collection::value_type(key, value));
+  if (!ret.second) {
+    // update
+    ret.first->second = value;
+    return false;
+  }
+  return true;
+}
+
+// Insert a new key and value into a map or hash_map.
+// If the key is not present in the map the key and value are
+// inserted, otherwise nothing happens. True indicates that an insert
+// took place, false indicates the key was already present.
+template <class Collection, class Key, class Value>
+bool InsertIfNotPresent(Collection * const collection,
+                        const Key& key, const Value& value) {
+  pair<typename Collection::iterator, bool> ret =
+    collection->insert(typename Collection::value_type(key, value));
+  return ret.second;
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
diff --git a/src/google/protobuf/stubs/stl_util-inl.cc b/src/google/protobuf/stubs/stl_util-inl.cc
new file mode 100644
index 0000000..445c646
--- /dev/null
+++ b/src/google/protobuf/stubs/stl_util-inl.cc
@@ -0,0 +1,27 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// from google3/util/gtl/stl_util-inl.cc
+
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+
+// Template module.  Nothing to see here.
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/stubs/stl_util-inl.h b/src/google/protobuf/stubs/stl_util-inl.h
new file mode 100644
index 0000000..db079a7
--- /dev/null
+++ b/src/google/protobuf/stubs/stl_util-inl.h
@@ -0,0 +1,107 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// from google3/util/gtl/stl_util-inl.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
+#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// STLDeleteContainerPointers()
+//  For a range within a container of pointers, calls delete
+//  (non-array version) on these pointers.
+// NOTE: for these three functions, we could just implement a DeleteObject
+// functor and then call for_each() on the range and functor, but this
+// requires us to pull in all of algorithm.h, which seems expensive.
+// For hash_[multi]set, it is important that this deletes behind the iterator
+// because the hash_set may call the hash function on the iterator when it is
+// advanced, which could result in the hash function trying to deference a
+// stale pointer.
+template <class ForwardIterator>
+void STLDeleteContainerPointers(ForwardIterator begin,
+                                ForwardIterator end) {
+  while (begin != end) {
+    ForwardIterator temp = begin;
+    ++begin;
+    delete *temp;
+  }
+}
+
+// Inside Google, this function implements a horrible, disgusting hack in which
+// we reach into the string's private implementation and resize it without
+// initializing the new bytes.  In some cases doing this can significantly
+// improve performance.  However, since it's totally non-portable it has no
+// place in open source code.  Feel free to fill this function in with your
+// own disgusting hack if you want the perf boost.
+inline void STLStringResizeUninitialized(string* s, size_t new_size) {
+  s->resize(new_size);
+}
+
+// Return a mutable char* pointing to a string's internal buffer,
+// which may not be null-terminated. Writing through this pointer will
+// modify the string.
+//
+// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
+// next call to a string method that invalidates iterators.
+//
+// As of 2006-04, there is no standard-blessed way of getting a
+// mutable reference to a string's internal buffer. However, issue 530
+// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530)
+// proposes this as the method. According to Matt Austern, this should
+// already work on all current implementations.
+inline char* string_as_array(string* str) {
+  // DO NOT USE const_cast<char*>(str->data())! See the unittest for why.
+  return str->empty() ? NULL : &*str->begin();
+}
+
+// STLDeleteElements() deletes all the elements in an STL container and clears
+// the container.  This function is suitable for use with a vector, set,
+// hash_set, or any other STL container which defines sensible begin(), end(),
+// and clear() methods.
+//
+// If container is NULL, this function is a no-op.
+//
+// As an alternative to calling STLDeleteElements() directly, consider
+// ElementDeleter (defined below), which ensures that your container's elements
+// are deleted when the ElementDeleter goes out of scope.
+template <class T>
+void STLDeleteElements(T *container) {
+  if (!container) return;
+  STLDeleteContainerPointers(container->begin(), container->end());
+  container->clear();
+}
+
+// Given an STL container consisting of (key, value) pairs, STLDeleteValues
+// deletes all the "value" components and clears the container.  Does nothing
+// in the case it's given a NULL pointer.
+
+template <class T>
+void STLDeleteValues(T *v) {
+  if (!v) return;
+  for (typename T::iterator i = v->begin(); i != v->end(); ++i) {
+    delete i->second;
+  }
+  v->clear();
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
new file mode 100644
index 0000000..07caaf7
--- /dev/null
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -0,0 +1,1121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// from google3/strings/strutil.cc
+
+#include <google/protobuf/stubs/strutil.h>
+#include <errno.h>
+#include <float.h>    // FLT_DIG and DBL_DIG
+#include <limits>
+#include <limits.h>
+
+#ifdef _WIN32
+// MSVC has only _snprintf, not snprintf.
+//
+// MinGW has both snprintf and _snprintf, but they appear to be different
+// functions.  The former is buggy.  When invoked like so:
+//   char buffer[32];
+//   snprintf(buffer, 32, "%.*g\n", FLT_DIG, 1.23e10f);
+// it prints "1.23000e+10".  This is plainly wrong:  %g should never print
+// trailing zeros after the decimal point.  For some reason this bug only
+// occurs with some input values, not all.  In any case, _snprintf does the
+// right thing, so we use it.
+#define snprintf _snprintf
+#endif
+
+namespace google {
+namespace protobuf {
+
+inline bool IsNaN(double value) {
+  // NaN is never equal to anything, even itself.
+  return value != value;
+}
+
+// The definitions of these in ctype.h change based on locale.  Since our
+// string manipulation is all in relation to the protocol buffer and C++
+// languages, we always want to use the C locale.  So, we re-define these
+// exactly as we want them.
+static bool isxdigit(char c) {
+  return ('0' <= c && c <= '9') ||
+         ('a' <= c && c <= 'f') ||
+         ('A' <= c && c <= 'F');
+}
+
+static bool isprint(char c) {
+  return c >= 0x20 && c <= 0x7E;
+}
+
+// ----------------------------------------------------------------------
+// StripString
+//    Replaces any occurrence of the character 'remove' (or the characters
+//    in 'remove') with the character 'replacewith'.
+// ----------------------------------------------------------------------
+void StripString(string* s, const char* remove, char replacewith) {
+  const char * str_start = s->c_str();
+  const char * str = str_start;
+  for (str = strpbrk(str, remove);
+       str != NULL;
+       str = strpbrk(str + 1, remove)) {
+    (*s)[str - str_start] = replacewith;
+  }
+}
+
+// ----------------------------------------------------------------------
+// StringReplace()
+//    Replace the "old" pattern with the "new" pattern in a string,
+//    and append the result to "res".  If replace_all is false,
+//    it only replaces the first instance of "old."
+// ----------------------------------------------------------------------
+
+void StringReplace(const string& s, const string& oldsub,
+                   const string& newsub, bool replace_all,
+                   string* res) {
+  if (oldsub.empty()) {
+    res->append(s);  // if empty, append the given string.
+    return;
+  }
+
+  string::size_type start_pos = 0;
+  string::size_type pos;
+  do {
+    pos = s.find(oldsub, start_pos);
+    if (pos == string::npos) {
+      break;
+    }
+    res->append(s, start_pos, pos - start_pos);
+    res->append(newsub);
+    start_pos = pos + oldsub.size();  // start searching again after the "old"
+  } while (replace_all);
+  res->append(s, start_pos, s.length() - start_pos);
+}
+
+// ----------------------------------------------------------------------
+// StringReplace()
+//    Give me a string and two patterns "old" and "new", and I replace
+//    the first instance of "old" in the string with "new", if it
+//    exists.  If "global" is true; call this repeatedly until it
+//    fails.  RETURN a new string, regardless of whether the replacement
+//    happened or not.
+// ----------------------------------------------------------------------
+
+string StringReplace(const string& s, const string& oldsub,
+                     const string& newsub, bool replace_all) {
+  string ret;
+  StringReplace(s, oldsub, newsub, replace_all, &ret);
+  return ret;
+}
+
+// ----------------------------------------------------------------------
+// SplitStringUsing()
+//    Split a string using a character delimiter. Append the components
+//    to 'result'.
+//
+// Note: For multi-character delimiters, this routine will split on *ANY* of
+// the characters in the string, not the entire string as a single delimiter.
+// ----------------------------------------------------------------------
+template <typename ITR>
+static inline
+void SplitStringToIteratorUsing(const string& full,
+                                const char* delim,
+                                ITR& result) {
+  // Optimize the common case where delim is a single character.
+  if (delim[0] != '\0' && delim[1] == '\0') {
+    char c = delim[0];
+    const char* p = full.data();
+    const char* end = p + full.size();
+    while (p != end) {
+      if (*p == c) {
+        ++p;
+      } else {
+        const char* start = p;
+        while (++p != end && *p != c);
+        *result++ = string(start, p - start);
+      }
+    }
+    return;
+  }
+
+  string::size_type begin_index, end_index;
+  begin_index = full.find_first_not_of(delim);
+  while (begin_index != string::npos) {
+    end_index = full.find_first_of(delim, begin_index);
+    if (end_index == string::npos) {
+      *result++ = full.substr(begin_index);
+      return;
+    }
+    *result++ = full.substr(begin_index, (end_index - begin_index));
+    begin_index = full.find_first_not_of(delim, end_index);
+  }
+}
+
+void SplitStringUsing(const string& full,
+                      const char* delim,
+                      vector<string>* result) {
+  back_insert_iterator< vector<string> > it(*result);
+  SplitStringToIteratorUsing(full, delim, it);
+}
+
+// ----------------------------------------------------------------------
+// JoinStrings()
+//    This merges a vector of string components with delim inserted
+//    as separaters between components.
+//
+// ----------------------------------------------------------------------
+template <class ITERATOR>
+static void JoinStringsIterator(const ITERATOR& start,
+                                const ITERATOR& end,
+                                const char* delim,
+                                string* result) {
+  GOOGLE_CHECK(result != NULL);
+  result->clear();
+  int delim_length = strlen(delim);
+
+  // Precompute resulting length so we can reserve() memory in one shot.
+  int length = 0;
+  for (ITERATOR iter = start; iter != end; ++iter) {
+    if (iter != start) {
+      length += delim_length;
+    }
+    length += iter->size();
+  }
+  result->reserve(length);
+
+  // Now combine everything.
+  for (ITERATOR iter = start; iter != end; ++iter) {
+    if (iter != start) {
+      result->append(delim, delim_length);
+    }
+    result->append(iter->data(), iter->size());
+  }
+}
+
+void JoinStrings(const vector<string>& components,
+                 const char* delim,
+                 string * result) {
+  JoinStringsIterator(components.begin(), components.end(), delim, result);
+}
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeSequences()
+//    This does all the unescaping that C does: \ooo, \r, \n, etc
+//    Returns length of resulting string.
+//    The implementation of \x parses any positive number of hex digits,
+//    but it is an error if the value requires more than 8 bits, and the
+//    result is truncated to 8 bits.
+//
+//    The second call stores its errors in a supplied string vector.
+//    If the string vector pointer is NULL, it reports the errors with LOG().
+// ----------------------------------------------------------------------
+
+#define IS_OCTAL_DIGIT(c) (((c) >= '0') && ((c) <= '7'))
+
+inline int hex_digit_to_int(char c) {
+  /* Assume ASCII. */
+  assert('0' == 0x30 && 'A' == 0x41 && 'a' == 0x61);
+  assert(isxdigit(c));
+  int x = static_cast<unsigned char>(c);
+  if (x > '9') {
+    x += 9;
+  }
+  return x & 0xf;
+}
+
+// Protocol buffers doesn't ever care about errors, but I don't want to remove
+// the code.
+#define LOG_STRING(LEVEL, VECTOR) GOOGLE_LOG_IF(LEVEL, false)
+
+int UnescapeCEscapeSequences(const char* source, char* dest) {
+  return UnescapeCEscapeSequences(source, dest, NULL);
+}
+
+int UnescapeCEscapeSequences(const char* source, char* dest,
+                             vector<string> *errors) {
+  GOOGLE_DCHECK(errors == NULL) << "Error reporting not implemented.";
+
+  char* d = dest;
+  const char* p = source;
+
+  // Small optimization for case where source = dest and there's no escaping
+  while ( p == d && *p != '\0' && *p != '\\' )
+    p++, d++;
+
+  while (*p != '\0') {
+    if (*p != '\\') {
+      *d++ = *p++;
+    } else {
+      switch ( *++p ) {                    // skip past the '\\'
+        case '\0':
+          LOG_STRING(ERROR, errors) << "String cannot end with \\";
+          *d = '\0';
+          return d - dest;   // we're done with p
+        case 'a':  *d++ = '\a';  break;
+        case 'b':  *d++ = '\b';  break;
+        case 'f':  *d++ = '\f';  break;
+        case 'n':  *d++ = '\n';  break;
+        case 'r':  *d++ = '\r';  break;
+        case 't':  *d++ = '\t';  break;
+        case 'v':  *d++ = '\v';  break;
+        case '\\': *d++ = '\\';  break;
+        case '?':  *d++ = '\?';  break;    // \?  Who knew?
+        case '\'': *d++ = '\'';  break;
+        case '"':  *d++ = '\"';  break;
+        case '0': case '1': case '2': case '3':  // octal digit: 1 to 3 digits
+        case '4': case '5': case '6': case '7': {
+          char ch = *p - '0';
+          if ( IS_OCTAL_DIGIT(p[1]) )
+            ch = ch * 8 + *++p - '0';
+          if ( IS_OCTAL_DIGIT(p[1]) )      // safe (and easy) to do this twice
+            ch = ch * 8 + *++p - '0';      // now points at last digit
+          *d++ = ch;
+          break;
+        }
+        case 'x': case 'X': {
+          if (!isxdigit(p[1])) {
+            if (p[1] == '\0') {
+              LOG_STRING(ERROR, errors) << "String cannot end with \\x";
+            } else {
+              LOG_STRING(ERROR, errors) <<
+                "\\x cannot be followed by non-hex digit: \\" << *p << p[1];
+            }
+            break;
+          }
+          unsigned int ch = 0;
+          const char *hex_start = p;
+          while (isxdigit(p[1]))  // arbitrarily many hex digits
+            ch = (ch << 4) + hex_digit_to_int(*++p);
+          if (ch > 0xFF)
+            LOG_STRING(ERROR, errors) << "Value of " <<
+              "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits";
+          *d++ = ch;
+          break;
+        }
+#if 0  // TODO(kenton):  Support \u and \U?  Requires runetochar().
+        case 'u': {
+          // \uhhhh => convert 4 hex digits to UTF-8
+          char32 rune = 0;
+          const char *hex_start = p;
+          for (int i = 0; i < 4; ++i) {
+            if (isxdigit(p[1])) {  // Look one char ahead.
+              rune = (rune << 4) + hex_digit_to_int(*++p);  // Advance p.
+            } else {
+              LOG_STRING(ERROR, errors)
+                << "\\u must be followed by 4 hex digits: \\"
+                <<  string(hex_start, p+1-hex_start);
+              break;
+            }
+          }
+          d += runetochar(d, &rune);
+          break;
+        }
+        case 'U': {
+          // \Uhhhhhhhh => convert 8 hex digits to UTF-8
+          char32 rune = 0;
+          const char *hex_start = p;
+          for (int i = 0; i < 8; ++i) {
+            if (isxdigit(p[1])) {  // Look one char ahead.
+              // Don't change rune until we're sure this
+              // is within the Unicode limit, but do advance p.
+              char32 newrune = (rune << 4) + hex_digit_to_int(*++p);
+              if (newrune > 0x10FFFF) {
+                LOG_STRING(ERROR, errors)
+                  << "Value of \\"
+                  << string(hex_start, p + 1 - hex_start)
+                  << " exceeds Unicode limit (0x10FFFF)";
+                break;
+              } else {
+                rune = newrune;
+              }
+            } else {
+              LOG_STRING(ERROR, errors)
+                << "\\U must be followed by 8 hex digits: \\"
+                <<  string(hex_start, p+1-hex_start);
+              break;
+            }
+          }
+          d += runetochar(d, &rune);
+          break;
+        }
+#endif
+        default:
+          LOG_STRING(ERROR, errors) << "Unknown escape sequence: \\" << *p;
+      }
+      p++;                                 // read past letter we escaped
+    }
+  }
+  *d = '\0';
+  return d - dest;
+}
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeString()
+//    This does the same thing as UnescapeCEscapeSequences, but creates
+//    a new string. The caller does not need to worry about allocating
+//    a dest buffer. This should be used for non performance critical
+//    tasks such as printing debug messages. It is safe for src and dest
+//    to be the same.
+//
+//    The second call stores its errors in a supplied string vector.
+//    If the string vector pointer is NULL, it reports the errors with LOG().
+//
+//    In the first and second calls, the length of dest is returned. In the
+//    the third call, the new string is returned.
+// ----------------------------------------------------------------------
+int UnescapeCEscapeString(const string& src, string* dest) {
+  return UnescapeCEscapeString(src, dest, NULL);
+}
+
+int UnescapeCEscapeString(const string& src, string* dest,
+                          vector<string> *errors) {
+  scoped_array<char> unescaped(new char[src.size() + 1]);
+  int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors);
+  GOOGLE_CHECK(dest);
+  dest->assign(unescaped.get(), len);
+  return len;
+}
+
+string UnescapeCEscapeString(const string& src) {
+  scoped_array<char> unescaped(new char[src.size() + 1]);
+  int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), NULL);
+  return string(unescaped.get(), len);
+}
+
+// ----------------------------------------------------------------------
+// CEscapeString()
+// CHexEscapeString()
+//    Copies 'src' to 'dest', escaping dangerous characters using
+//    C-style escape sequences. This is very useful for preparing query
+//    flags. 'src' and 'dest' should not overlap. The 'Hex' version uses
+//    hexadecimal rather than octal sequences.
+//    Returns the number of bytes written to 'dest' (not including the \0)
+//    or -1 if there was insufficient space.
+//
+//    Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// ----------------------------------------------------------------------
+static int CEscapeInternal(const char* src, int src_len, char* dest,
+                           int dest_len, bool use_hex) {
+  const char* src_end = src + src_len;
+  int used = 0;
+  bool last_hex_escape = false; // true if last output char was \xNN
+
+  for (; src < src_end; src++) {
+    if (dest_len - used < 2)   // Need space for two letter escape
+      return -1;
+
+    bool is_hex_escape = false;
+    switch (*src) {
+      case '\n': dest[used++] = '\\'; dest[used++] = 'n';  break;
+      case '\r': dest[used++] = '\\'; dest[used++] = 'r';  break;
+      case '\t': dest[used++] = '\\'; dest[used++] = 't';  break;
+      case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break;
+      case '\'': dest[used++] = '\\'; dest[used++] = '\''; break;
+      case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break;
+      default:
+        // Note that if we emit \xNN and the src character after that is a hex
+        // digit then that digit must be escaped too to prevent it being
+        // interpreted as part of the character code by C.
+        if (!isprint(*src) || (last_hex_escape && isxdigit(*src))) {
+          if (dest_len - used < 4) // need space for 4 letter escape
+            return -1;
+          sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"),
+                  static_cast<uint8>(*src));
+          is_hex_escape = use_hex;
+          used += 4;
+        } else {
+          dest[used++] = *src; break;
+        }
+    }
+    last_hex_escape = is_hex_escape;
+  }
+
+  if (dest_len - used < 1)   // make sure that there is room for \0
+    return -1;
+
+  dest[used] = '\0';   // doesn't count towards return value though
+  return used;
+}
+
+int CEscapeString(const char* src, int src_len, char* dest, int dest_len) {
+  return CEscapeInternal(src, src_len, dest, dest_len, false);
+}
+
+// ----------------------------------------------------------------------
+// CEscape()
+// CHexEscape()
+//    Copies 'src' to result, escaping dangerous characters using
+//    C-style escape sequences. This is very useful for preparing query
+//    flags. 'src' and 'dest' should not overlap. The 'Hex' version
+//    hexadecimal rather than octal sequences.
+//
+//    Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// ----------------------------------------------------------------------
+string CEscape(const string& src) {
+  const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
+  scoped_array<char> dest(new char[dest_length]);
+  const int len = CEscapeInternal(src.data(), src.size(),
+                                  dest.get(), dest_length, false);
+  GOOGLE_DCHECK_GE(len, 0);
+  return string(dest.get(), len);
+}
+
+// ----------------------------------------------------------------------
+// strto32_adaptor()
+// strtou32_adaptor()
+//    Implementation of strto[u]l replacements that have identical
+//    overflow and underflow characteristics for both ILP-32 and LP-64
+//    platforms, including errno preservation in error-free calls.
+// ----------------------------------------------------------------------
+
+int32 strto32_adaptor(const char *nptr, char **endptr, int base) {
+  const int saved_errno = errno;
+  errno = 0;
+  const long result = strtol(nptr, endptr, base);
+  if (errno == ERANGE && result == LONG_MIN) {
+    return kint32min;
+  } else if (errno == ERANGE && result == LONG_MAX) {
+    return kint32max;
+  } else if (errno == 0 && result < kint32min) {
+    errno = ERANGE;
+    return kint32min;
+  } else if (errno == 0 && result > kint32max) {
+    errno = ERANGE;
+    return kint32max;
+  }
+  if (errno == 0)
+    errno = saved_errno;
+  return static_cast<int32>(result);
+}
+
+uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) {
+  const int saved_errno = errno;
+  errno = 0;
+  const unsigned long result = strtoul(nptr, endptr, base);
+  if (errno == ERANGE && result == ULONG_MAX) {
+    return kuint32max;
+  } else if (errno == 0 && result > kuint32max) {
+    errno = ERANGE;
+    return kuint32max;
+  }
+  if (errno == 0)
+    errno = saved_errno;
+  return static_cast<uint32>(result);
+}
+
+// ----------------------------------------------------------------------
+// FastIntToBuffer()
+// FastInt64ToBuffer()
+// FastHexToBuffer()
+// FastHex64ToBuffer()
+// FastHex32ToBuffer()
+// ----------------------------------------------------------------------
+
+// Offset into buffer where FastInt64ToBuffer places the end of string
+// null character.  Also used by FastInt64ToBufferLeft.
+static const int kFastInt64ToBufferOffset = 21;
+
+char *FastInt64ToBuffer(int64 i, char* buffer) {
+  // We could collapse the positive and negative sections, but that
+  // would be slightly slower for positive numbers...
+  // 22 bytes is enough to store -2**64, -18446744073709551616.
+  char* p = buffer + kFastInt64ToBufferOffset;
+  *p-- = '\0';
+  if (i >= 0) {
+    do {
+      *p-- = '0' + i % 10;
+      i /= 10;
+    } while (i > 0);
+    return p + 1;
+  } else {
+    // On different platforms, % and / have different behaviors for
+    // negative numbers, so we need to jump through hoops to make sure
+    // we don't divide negative numbers.
+    if (i > -10) {
+      i = -i;
+      *p-- = '0' + i;
+      *p = '-';
+      return p;
+    } else {
+      // Make sure we aren't at MIN_INT, in which case we can't say i = -i
+      i = i + 10;
+      i = -i;
+      *p-- = '0' + i % 10;
+      // Undo what we did a moment ago
+      i = i / 10 + 1;
+      do {
+        *p-- = '0' + i % 10;
+        i /= 10;
+      } while (i > 0);
+      *p = '-';
+      return p;
+    }
+  }
+}
+
+// Offset into buffer where FastInt32ToBuffer places the end of string
+// null character.  Also used by FastInt32ToBufferLeft
+static const int kFastInt32ToBufferOffset = 11;
+
+// Yes, this is a duplicate of FastInt64ToBuffer.  But, we need this for the
+// compiler to generate 32 bit arithmetic instructions.  It's much faster, at
+// least with 32 bit binaries.
+char *FastInt32ToBuffer(int32 i, char* buffer) {
+  // We could collapse the positive and negative sections, but that
+  // would be slightly slower for positive numbers...
+  // 12 bytes is enough to store -2**32, -4294967296.
+  char* p = buffer + kFastInt32ToBufferOffset;
+  *p-- = '\0';
+  if (i >= 0) {
+    do {
+      *p-- = '0' + i % 10;
+      i /= 10;
+    } while (i > 0);
+    return p + 1;
+  } else {
+    // On different platforms, % and / have different behaviors for
+    // negative numbers, so we need to jump through hoops to make sure
+    // we don't divide negative numbers.
+    if (i > -10) {
+      i = -i;
+      *p-- = '0' + i;
+      *p = '-';
+      return p;
+    } else {
+      // Make sure we aren't at MIN_INT, in which case we can't say i = -i
+      i = i + 10;
+      i = -i;
+      *p-- = '0' + i % 10;
+      // Undo what we did a moment ago
+      i = i / 10 + 1;
+      do {
+        *p-- = '0' + i % 10;
+        i /= 10;
+      } while (i > 0);
+      *p = '-';
+      return p;
+    }
+  }
+}
+
+char *FastHexToBuffer(int i, char* buffer) {
+  GOOGLE_CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i;
+
+  static const char *hexdigits = "0123456789abcdef";
+  char *p = buffer + 21;
+  *p-- = '\0';
+  do {
+    *p-- = hexdigits[i & 15];   // mod by 16
+    i >>= 4;                    // divide by 16
+  } while (i > 0);
+  return p + 1;
+}
+
+char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) {
+  static const char *hexdigits = "0123456789abcdef";
+  buffer[num_byte] = '\0';
+  for (int i = num_byte - 1; i >= 0; i--) {
+    buffer[i] = hexdigits[uint32(value) & 0xf];
+    value >>= 4;
+  }
+  return buffer;
+}
+
+char *FastHex64ToBuffer(uint64 value, char* buffer) {
+  return InternalFastHexToBuffer(value, buffer, 16);
+}
+
+char *FastHex32ToBuffer(uint32 value, char* buffer) {
+  return InternalFastHexToBuffer(value, buffer, 8);
+}
+
+static inline char* PlaceNum(char* p, int num, char prev_sep) {
+   *p-- = '0' + num % 10;
+   *p-- = '0' + num / 10;
+   *p-- = prev_sep;
+   return p;
+}
+
+// ----------------------------------------------------------------------
+// FastInt32ToBufferLeft()
+// FastUInt32ToBufferLeft()
+// FastInt64ToBufferLeft()
+// FastUInt64ToBufferLeft()
+//
+// Like the Fast*ToBuffer() functions above, these are intended for speed.
+// Unlike the Fast*ToBuffer() functions, however, these functions write
+// their output to the beginning of the buffer (hence the name, as the
+// output is left-aligned).  The caller is responsible for ensuring that
+// the buffer has enough space to hold the output.
+//
+// Returns a pointer to the end of the string (i.e. the null character
+// terminating the string).
+// ----------------------------------------------------------------------
+
+static const char two_ASCII_digits[100][2] = {
+  {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'},
+  {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'},
+  {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'},
+  {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'},
+  {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'},
+  {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'},
+  {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'},
+  {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'},
+  {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'},
+  {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'},
+  {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'},
+  {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'},
+  {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'},
+  {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'},
+  {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'},
+  {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'},
+  {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'},
+  {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'},
+  {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'},
+  {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'}
+};
+
+char* FastUInt32ToBufferLeft(uint32 u, char* buffer) {
+  int digits;
+  const char *ASCII_digits = NULL;
+  // The idea of this implementation is to trim the number of divides to as few
+  // as possible by using multiplication and subtraction rather than mod (%),
+  // and by outputting two digits at a time rather than one.
+  // The huge-number case is first, in the hopes that the compiler will output
+  // that case in one branch-free block of code, and only output conditional
+  // branches into it from below.
+  if (u >= 1000000000) {  // >= 1,000,000,000
+    digits = u / 100000000;  // 100,000,000
+    ASCII_digits = two_ASCII_digits[digits];
+    buffer[0] = ASCII_digits[0];
+    buffer[1] = ASCII_digits[1];
+    buffer += 2;
+sublt100_000_000:
+    u -= digits * 100000000;  // 100,000,000
+lt100_000_000:
+    digits = u / 1000000;  // 1,000,000
+    ASCII_digits = two_ASCII_digits[digits];
+    buffer[0] = ASCII_digits[0];
+    buffer[1] = ASCII_digits[1];
+    buffer += 2;
+sublt1_000_000:
+    u -= digits * 1000000;  // 1,000,000
+lt1_000_000:
+    digits = u / 10000;  // 10,000
+    ASCII_digits = two_ASCII_digits[digits];
+    buffer[0] = ASCII_digits[0];
+    buffer[1] = ASCII_digits[1];
+    buffer += 2;
+sublt10_000:
+    u -= digits * 10000;  // 10,000
+lt10_000:
+    digits = u / 100;
+    ASCII_digits = two_ASCII_digits[digits];
+    buffer[0] = ASCII_digits[0];
+    buffer[1] = ASCII_digits[1];
+    buffer += 2;
+sublt100:
+    u -= digits * 100;
+lt100:
+    digits = u;
+    ASCII_digits = two_ASCII_digits[digits];
+    buffer[0] = ASCII_digits[0];
+    buffer[1] = ASCII_digits[1];
+    buffer += 2;
+done:
+    *buffer = 0;
+    return buffer;
+  }
+
+  if (u < 100) {
+    digits = u;
+    if (u >= 10) goto lt100;
+    *buffer++ = '0' + digits;
+    goto done;
+  }
+  if (u  <  10000) {   // 10,000
+    if (u >= 1000) goto lt10_000;
+    digits = u / 100;
+    *buffer++ = '0' + digits;
+    goto sublt100;
+  }
+  if (u  <  1000000) {   // 1,000,000
+    if (u >= 100000) goto lt1_000_000;
+    digits = u / 10000;  //    10,000
+    *buffer++ = '0' + digits;
+    goto sublt10_000;
+  }
+  if (u  <  100000000) {   // 100,000,000
+    if (u >= 10000000) goto lt100_000_000;
+    digits = u / 1000000;  //   1,000,000
+    *buffer++ = '0' + digits;
+    goto sublt1_000_000;
+  }
+  // we already know that u < 1,000,000,000
+  digits = u / 100000000;   // 100,000,000
+  *buffer++ = '0' + digits;
+  goto sublt100_000_000;
+}
+
+char* FastInt32ToBufferLeft(int32 i, char* buffer) {
+  uint32 u = i;
+  if (i < 0) {
+    *buffer++ = '-';
+    u = -i;
+  }
+  return FastUInt32ToBufferLeft(u, buffer);
+}
+
+char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) {
+  int digits;
+  const char *ASCII_digits = NULL;
+
+  uint32 u = static_cast<uint32>(u64);
+  if (u == u64) return FastUInt32ToBufferLeft(u, buffer);
+
+  uint64 top_11_digits = u64 / 1000000000;
+  buffer = FastUInt64ToBufferLeft(top_11_digits, buffer);
+  u = u64 - (top_11_digits * 1000000000);
+
+  digits = u / 10000000;  // 10,000,000
+  GOOGLE_DCHECK_LT(digits, 100);
+  ASCII_digits = two_ASCII_digits[digits];
+  buffer[0] = ASCII_digits[0];
+  buffer[1] = ASCII_digits[1];
+  buffer += 2;
+  u -= digits * 10000000;  // 10,000,000
+  digits = u / 100000;  // 100,000
+  ASCII_digits = two_ASCII_digits[digits];
+  buffer[0] = ASCII_digits[0];
+  buffer[1] = ASCII_digits[1];
+  buffer += 2;
+  u -= digits * 100000;  // 100,000
+  digits = u / 1000;  // 1,000
+  ASCII_digits = two_ASCII_digits[digits];
+  buffer[0] = ASCII_digits[0];
+  buffer[1] = ASCII_digits[1];
+  buffer += 2;
+  u -= digits * 1000;  // 1,000
+  digits = u / 10;
+  ASCII_digits = two_ASCII_digits[digits];
+  buffer[0] = ASCII_digits[0];
+  buffer[1] = ASCII_digits[1];
+  buffer += 2;
+  u -= digits * 10;
+  digits = u;
+  *buffer++ = '0' + digits;
+  *buffer = 0;
+  return buffer;
+}
+
+char* FastInt64ToBufferLeft(int64 i, char* buffer) {
+  uint64 u = i;
+  if (i < 0) {
+    *buffer++ = '-';
+    u = -i;
+  }
+  return FastUInt64ToBufferLeft(u, buffer);
+}
+
+// ----------------------------------------------------------------------
+// SimpleItoa()
+//    Description: converts an integer to a string.
+//
+//    Return value: string
+// ----------------------------------------------------------------------
+
+string SimpleItoa(int i) {
+  char buffer[kFastToBufferSize];
+  return (sizeof(i) == 4) ?
+    FastInt32ToBuffer(i, buffer) :
+    FastInt64ToBuffer(i, buffer);
+}
+
+string SimpleItoa(unsigned int i) {
+  char buffer[kFastToBufferSize];
+  return string(buffer, (sizeof(i) == 4) ?
+    FastUInt32ToBufferLeft(i, buffer) :
+    FastUInt64ToBufferLeft(i, buffer));
+}
+
+string SimpleItoa(long i) {
+  char buffer[kFastToBufferSize];
+  return (sizeof(i) == 4) ?
+    FastInt32ToBuffer(i, buffer) :
+    FastInt64ToBuffer(i, buffer);
+}
+
+string SimpleItoa(unsigned long i) {
+  char buffer[kFastToBufferSize];
+  return string(buffer, (sizeof(i) == 4) ?
+    FastUInt32ToBufferLeft(i, buffer) :
+    FastUInt64ToBufferLeft(i, buffer));
+}
+
+string SimpleItoa(long long i) {
+  char buffer[kFastToBufferSize];
+  return (sizeof(i) == 4) ?
+    FastInt32ToBuffer(i, buffer) :
+    FastInt64ToBuffer(i, buffer);
+}
+
+string SimpleItoa(unsigned long long i) {
+  char buffer[kFastToBufferSize];
+  return string(buffer, (sizeof(i) == 4) ?
+    FastUInt32ToBufferLeft(i, buffer) :
+    FastUInt64ToBufferLeft(i, buffer));
+}
+
+// ----------------------------------------------------------------------
+// SimpleDtoa()
+// SimpleFtoa()
+// DoubleToBuffer()
+// FloatToBuffer()
+//    We want to print the value without losing precision, but we also do
+//    not want to print more digits than necessary.  This turns out to be
+//    trickier than it sounds.  Numbers like 0.2 cannot be represented
+//    exactly in binary.  If we print 0.2 with a very large precision,
+//    e.g. "%.50g", we get "0.2000000000000000111022302462515654042363167".
+//    On the other hand, if we set the precision too low, we lose
+//    significant digits when printing numbers that actually need them.
+//    It turns out there is no precision value that does the right thing
+//    for all numbers.
+//
+//    Our strategy is to first try printing with a precision that is never
+//    over-precise, then parse the result with strtod() to see if it
+//    matches.  If not, we print again with a precision that will always
+//    give a precise result, but may use more digits than necessary.
+//
+//    An arguably better strategy would be to use the algorithm described
+//    in "How to Print Floating-Point Numbers Accurately" by Steele &
+//    White, e.g. as implemented by David M. Gay's dtoa().  It turns out,
+//    however, that the following implementation is about as fast as
+//    DMG's code.  Furthermore, DMG's code locks mutexes, which means it
+//    will not scale well on multi-core machines.  DMG's code is slightly
+//    more accurate (in that it will never use more digits than
+//    necessary), but this is probably irrelevant for most users.
+//
+//    Rob Pike and Ken Thompson also have an implementation of dtoa() in
+//    third_party/fmt/fltfmt.cc.  Their implementation is similar to this
+//    one in that it makes guesses and then uses strtod() to check them.
+//    Their implementation is faster because they use their own code to
+//    generate the digits in the first place rather than use snprintf(),
+//    thus avoiding format string parsing overhead.  However, this makes
+//    it considerably more complicated than the following implementation,
+//    and it is embedded in a larger library.  If speed turns out to be
+//    an issue, we could re-implement this in terms of their
+//    implementation.
+// ----------------------------------------------------------------------
+
+string SimpleDtoa(double value) {
+  char buffer[kDoubleToBufferSize];
+  return DoubleToBuffer(value, buffer);
+}
+
+string SimpleFtoa(float value) {
+  char buffer[kFloatToBufferSize];
+  return FloatToBuffer(value, buffer);
+}
+
+static inline bool IsValidFloatChar(char c) {
+  return ('0' <= c && c <= '9') ||
+         c == 'e' || c == 'E' ||
+         c == '+' || c == '-';
+}
+
+void DelocalizeRadix(char* buffer) {
+  // Fast check:  if the buffer has a normal decimal point, assume no
+  // translation is needed.
+  if (strchr(buffer, '.') != NULL) return;
+
+  // Find the first unknown character.
+  while (IsValidFloatChar(*buffer)) ++buffer;
+
+  if (*buffer == '\0') {
+    // No radix character found.
+    return;
+  }
+
+  // We are now pointing at the locale-specific radix character.  Replace it
+  // with '.'.
+  *buffer = '.';
+  ++buffer;
+
+  if (!IsValidFloatChar(*buffer) && *buffer != '\0') {
+    // It appears the radix was a multi-byte character.  We need to remove the
+    // extra bytes.
+    char* target = buffer;
+    do { ++buffer; } while (!IsValidFloatChar(*buffer) && *buffer != '\0');
+    memmove(target, buffer, strlen(buffer) + 1);
+  }
+}
+
+char* DoubleToBuffer(double value, char* buffer) {
+  // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all
+  // platforms these days.  Just in case some system exists where DBL_DIG
+  // is significantly larger -- and risks overflowing our buffer -- we have
+  // this assert.
+  GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big);
+
+  if (value == numeric_limits<double>::infinity()) {
+    strcpy(buffer, "inf");
+    return buffer;
+  } else if (value == -numeric_limits<double>::infinity()) {
+    strcpy(buffer, "-inf");
+    return buffer;
+  } else if (IsNaN(value)) {
+    strcpy(buffer, "nan");
+    return buffer;
+  }
+
+  int snprintf_result =
+    snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value);
+
+  // The snprintf should never overflow because the buffer is significantly
+  // larger than the precision we asked for.
+  GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
+
+  // We need to make parsed_value volatile in order to force the compiler to
+  // write it out to the stack.  Otherwise, it may keep the value in a
+  // register, and if it does that, it may keep it as a long double instead
+  // of a double.  This long double may have extra bits that make it compare
+  // unequal to "value" even though it would be exactly equal if it were
+  // truncated to a double.
+  volatile double parsed_value = strtod(buffer, NULL);
+  if (parsed_value != value) {
+    int snprintf_result =
+      snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value);
+
+    // Should never overflow; see above.
+    GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
+  }
+
+  DelocalizeRadix(buffer);
+  return buffer;
+}
+
+bool safe_strtof(const char* str, float* value) {
+  char* endptr;
+  errno = 0;  // errno only gets set on errors
+#ifdef _WIN32  // has no strtof()
+  *value = strtod(str, &endptr);
+#else
+  *value = strtof(str, &endptr);
+#endif
+  return *str != 0 && *endptr == 0 && errno == 0;
+}
+
+char* FloatToBuffer(float value, char* buffer) {
+  // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all
+  // platforms these days.  Just in case some system exists where FLT_DIG
+  // is significantly larger -- and risks overflowing our buffer -- we have
+  // this assert.
+  GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big);
+
+  if (value == numeric_limits<double>::infinity()) {
+    strcpy(buffer, "inf");
+    return buffer;
+  } else if (value == -numeric_limits<double>::infinity()) {
+    strcpy(buffer, "-inf");
+    return buffer;
+  } else if (IsNaN(value)) {
+    strcpy(buffer, "nan");
+    return buffer;
+  }
+
+  int snprintf_result =
+    snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value);
+
+  // The snprintf should never overflow because the buffer is significantly
+  // larger than the precision we asked for.
+  GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
+
+  float parsed_value;
+  if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) {
+    int snprintf_result =
+      snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value);
+
+    // Should never overflow; see above.
+    GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
+  }
+
+  DelocalizeRadix(buffer);
+  return buffer;
+}
+
+// ----------------------------------------------------------------------
+// NoLocaleStrtod()
+//   This code will make you cry.
+// ----------------------------------------------------------------------
+
+// Returns a string identical to *input except that the character pointed to
+// by radix_pos (which should be '.') is replaced with the locale-specific
+// radix character.
+string LocalizeRadix(const char* input, const char* radix_pos) {
+  // Determine the locale-specific radix character by calling sprintf() to
+  // print the number 1.5, then stripping off the digits.  As far as I can
+  // tell, this is the only portable, thread-safe way to get the C library
+  // to divuldge the locale's radix character.  No, localeconv() is NOT
+  // thread-safe.
+  char temp[16];
+  int size = sprintf(temp, "%.1f", 1.5);
+  GOOGLE_CHECK_EQ(temp[0], '1');
+  GOOGLE_CHECK_EQ(temp[size-1], '5');
+  GOOGLE_CHECK_LE(size, 6);
+
+  // Now replace the '.' in the input with it.
+  string result;
+  result.reserve(strlen(input) + size - 3);
+  result.append(input, radix_pos);
+  result.append(temp + 1, size - 2);
+  result.append(radix_pos + 1);
+  return result;
+}
+
+double NoLocaleStrtod(const char* text, char** original_endptr) {
+  // We cannot simply set the locale to "C" temporarily with setlocale()
+  // as this is not thread-safe.  Instead, we try to parse in the current
+  // locale first.  If parsing stops at a '.' character, then this is a
+  // pretty good hint that we're actually in some other locale in which
+  // '.' is not the radix character.
+
+  char* temp_endptr;
+  double result = strtod(text, &temp_endptr);
+  if (original_endptr != NULL) *original_endptr = temp_endptr;
+  if (*temp_endptr != '.') return result;
+
+  // Parsing halted on a '.'.  Perhaps we're in a different locale?  Let's
+  // try to replace the '.' with a locale-specific radix character and
+  // try again.
+  string localized = LocalizeRadix(text, temp_endptr);
+  const char* localized_cstr = localized.c_str();
+  char* localized_endptr;
+  result = strtod(localized_cstr, &localized_endptr);
+  if ((localized_endptr - localized_cstr) >
+      (temp_endptr - text)) {
+    // This attempt got further, so replacing the decimal must have helped.
+    // Update original_endptr to point at the right location.
+    if (original_endptr != NULL) {
+      // size_diff is non-zero if the localized radix has multiple bytes.
+      int size_diff = localized.size() - strlen(text);
+      // const_cast is necessary to match the strtod() interface.
+      *original_endptr = const_cast<char*>(
+        text + (localized_endptr - localized_cstr - size_diff));
+    }
+  }
+
+  return result;
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h
new file mode 100644
index 0000000..ff91961
--- /dev/null
+++ b/src/google/protobuf/stubs/strutil.h
@@ -0,0 +1,432 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// from google3/strings/strutil.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
+#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
+
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _MSC_VER
+#define strtoll  _strtoi64
+#define strtoull _strtoui64
+#endif
+
+// ----------------------------------------------------------------------
+// ascii_isalnum()
+//    Check if an ASCII character is alphanumeric.  We can't use ctype's
+//    isalnum() because it is affected by locale.  This function is applied
+//    to identifiers in the protocol buffer language, not to natural-language
+//    strings, so locale should not be taken into account.
+// ascii_isdigit()
+//    Like above, but only accepts digits.
+// ----------------------------------------------------------------------
+
+inline bool ascii_isalnum(char c) {
+  return ('a' <= c && c <= 'z') ||
+         ('A' <= c && c <= 'Z') ||
+         ('0' <= c && c <= '9');
+}
+
+inline bool ascii_isdigit(char c) {
+  return ('0' <= c && c <= '9');
+}
+
+// ----------------------------------------------------------------------
+// HasPrefixString()
+//    Check if a string begins with a given prefix.
+// StripPrefixString()
+//    Given a string and a putative prefix, returns the string minus the
+//    prefix string if the prefix matches, otherwise the original
+//    string.
+// ----------------------------------------------------------------------
+inline bool HasPrefixString(const string& str,
+                            const string& prefix) {
+  return str.size() >= prefix.size() &&
+         str.compare(0, prefix.size(), prefix) == 0;
+}
+
+inline string StripPrefixString(const string& str, const string& prefix) {
+  if (HasPrefixString(str, prefix)) {
+    return str.substr(prefix.size());
+  } else {
+    return str;
+  }
+}
+
+// ----------------------------------------------------------------------
+// HasSuffixString()
+//    Return true if str ends in suffix.
+// StripSuffixString()
+//    Given a string and a putative suffix, returns the string minus the
+//    suffix string if the suffix matches, otherwise the original
+//    string.
+// ----------------------------------------------------------------------
+inline bool HasSuffixString(const string& str,
+                            const string& suffix) {
+  return str.size() >= suffix.size() &&
+         str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+inline string StripSuffixString(const string& str, const string& suffix) {
+  if (HasSuffixString(str, suffix)) {
+    return str.substr(0, str.size() - suffix.size());
+  } else {
+    return str;
+  }
+}
+
+// ----------------------------------------------------------------------
+// StripString
+//    Replaces any occurrence of the character 'remove' (or the characters
+//    in 'remove') with the character 'replacewith'.
+//    Good for keeping html characters or protocol characters (\t) out
+//    of places where they might cause a problem.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove,
+                                    char replacewith);
+
+// ----------------------------------------------------------------------
+// LowerString()
+// UpperString()
+//    Convert the characters in "s" to lowercase or uppercase.  ASCII-only:
+//    these functions intentionally ignore locale because they are applied to
+//    identifiers used in the Protocol Buffer language, not to natural-language
+//    strings.
+// ----------------------------------------------------------------------
+
+inline void LowerString(string * s) {
+  string::iterator end = s->end();
+  for (string::iterator i = s->begin(); i != end; ++i) {
+    // tolower() changes based on locale.  We don't want this!
+    if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A';
+  }
+}
+
+inline void UpperString(string * s) {
+  string::iterator end = s->end();
+  for (string::iterator i = s->begin(); i != end; ++i) {
+    // toupper() changes based on locale.  We don't want this!
+    if ('a' <= *i && *i <= 'z') *i += 'A' - 'a';
+  }
+}
+
+// ----------------------------------------------------------------------
+// StringReplace()
+//    Give me a string and two patterns "old" and "new", and I replace
+//    the first instance of "old" in the string with "new", if it
+//    exists.  RETURN a new string, regardless of whether the replacement
+//    happened or not.
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub,
+                                        const string& newsub, bool replace_all);
+
+// ----------------------------------------------------------------------
+// SplitStringUsing()
+//    Split a string using a character delimiter. Append the components
+//    to 'result'.  If there are consecutive delimiters, this function skips
+//    over all of them.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim,
+                                         vector<string>* res);
+
+// ----------------------------------------------------------------------
+// JoinStrings()
+//    These methods concatenate a vector of strings into a C++ string, using
+//    the C-string "delim" as a separator between components. There are two
+//    flavors of the function, one flavor returns the concatenated string,
+//    another takes a pointer to the target string. In the latter case the
+//    target string is cleared and overwritten.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void JoinStrings(const vector<string>& components,
+                                    const char* delim, string* result);
+
+inline string JoinStrings(const vector<string>& components,
+                          const char* delim) {
+  string result;
+  JoinStrings(components, delim, &result);
+  return result;
+}
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeSequences()
+//    Copies "source" to "dest", rewriting C-style escape sequences
+//    -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII
+//    equivalents.  "dest" must be sufficiently large to hold all
+//    the characters in the rewritten string (i.e. at least as large
+//    as strlen(source) + 1 should be safe, since the replacements
+//    are always shorter than the original escaped sequences).  It's
+//    safe for source and dest to be the same.  RETURNS the length
+//    of dest.
+//
+//    It allows hex sequences \xhh, or generally \xhhhhh with an
+//    arbitrary number of hex digits, but all of them together must
+//    specify a value of a single byte (e.g. \x0045 is equivalent
+//    to \x45, and \x1234 is erroneous).
+//
+//    It also allows escape sequences of the form \uhhhh (exactly four
+//    hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight
+//    hex digits, upper or lower case) to specify a Unicode code
+//    point. The dest array will contain the UTF8-encoded version of
+//    that code-point (e.g., if source contains \u2019, then dest will
+//    contain the three bytes 0xE2, 0x80, and 0x99). For the inverse
+//    transformation, use UniLib::UTF8EscapeString
+//    (util/utf8/unilib.h), not CEscapeString.
+//
+//    Errors: In the first form of the call, errors are reported with
+//    LOG(ERROR). The same is true for the second form of the call if
+//    the pointer to the string vector is NULL; otherwise, error
+//    messages are stored in the vector. In either case, the effect on
+//    the dest array is not defined, but rest of the source will be
+//    processed.
+//    ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest);
+LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest,
+                                                vector<string> *errors);
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeString()
+//    This does the same thing as UnescapeCEscapeSequences, but creates
+//    a new string. The caller does not need to worry about allocating
+//    a dest buffer. This should be used for non performance critical
+//    tasks such as printing debug messages. It is safe for src and dest
+//    to be the same.
+//
+//    The second call stores its errors in a supplied string vector.
+//    If the string vector pointer is NULL, it reports the errors with LOG().
+//
+//    In the first and second calls, the length of dest is returned. In the
+//    the third call, the new string is returned.
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest);
+LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest,
+                                             vector<string> *errors);
+LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src);
+
+// ----------------------------------------------------------------------
+// CEscapeString()
+//    Copies 'src' to 'dest', escaping dangerous characters using
+//    C-style escape sequences. This is very useful for preparing query
+//    flags. 'src' and 'dest' should not overlap.
+//    Returns the number of bytes written to 'dest' (not including the \0)
+//    or -1 if there was insufficient space.
+//
+//    Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len,
+                                     char* dest, int dest_len);
+
+// ----------------------------------------------------------------------
+// CEscape()
+//    More convenient form of CEscapeString: returns result as a "string".
+//    This version is slower than CEscapeString() because it does more
+//    allocation.  However, it is much more convenient to use in
+//    non-speed-critical code like logging messages etc.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string CEscape(const string& src);
+
+// ----------------------------------------------------------------------
+// strto32()
+// strtou32()
+// strto64()
+// strtou64()
+//    Architecture-neutral plug compatible replacements for strtol() and
+//    strtoul().  Long's have different lengths on ILP-32 and LP-64
+//    platforms, so using these is safer, from the point of view of
+//    overflow behavior, than using the standard libc functions.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char *nptr, char **endptr,
+                                         int base);
+LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char *nptr, char **endptr,
+                                           int base);
+
+inline int32 strto32(const char *nptr, char **endptr, int base) {
+  if (sizeof(int32) == sizeof(long))
+    return strtol(nptr, endptr, base);
+  else
+    return strto32_adaptor(nptr, endptr, base);
+}
+
+inline uint32 strtou32(const char *nptr, char **endptr, int base) {
+  if (sizeof(uint32) == sizeof(unsigned long))
+    return strtoul(nptr, endptr, base);
+  else
+    return strtou32_adaptor(nptr, endptr, base);
+}
+
+// For now, long long is 64-bit on all the platforms we care about, so these
+// functions can simply pass the call to strto[u]ll.
+inline int64 strto64(const char *nptr, char **endptr, int base) {
+  GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long),
+                        sizeof_int64_is_not_sizeof_long_long);
+  return strtoll(nptr, endptr, base);
+}
+
+inline uint64 strtou64(const char *nptr, char **endptr, int base) {
+  GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long),
+                        sizeof_uint64_is_not_sizeof_long_long);
+  return strtoull(nptr, endptr, base);
+}
+
+// ----------------------------------------------------------------------
+// FastIntToBuffer()
+// FastHexToBuffer()
+// FastHex64ToBuffer()
+// FastHex32ToBuffer()
+// FastTimeToBuffer()
+//    These are intended for speed.  FastIntToBuffer() assumes the
+//    integer is non-negative.  FastHexToBuffer() puts output in
+//    hex rather than decimal.  FastTimeToBuffer() puts the output
+//    into RFC822 format.
+//
+//    FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format,
+//    padded to exactly 16 bytes (plus one byte for '\0')
+//
+//    FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format,
+//    padded to exactly 8 bytes (plus one byte for '\0')
+//
+//       All functions take the output buffer as an arg.
+//    They all return a pointer to the beginning of the output,
+//    which may not be the beginning of the input buffer.
+// ----------------------------------------------------------------------
+
+// Suggested buffer size for FastToBuffer functions.  Also works with
+// DoubleToBuffer() and FloatToBuffer().
+static const int kFastToBufferSize = 32;
+
+LIBPROTOBUF_EXPORT char* FastInt32ToBuffer(int32 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastInt64ToBuffer(int64 i, char* buffer);
+char* FastUInt32ToBuffer(uint32 i, char* buffer);  // inline below
+char* FastUInt64ToBuffer(uint64 i, char* buffer);  // inline below
+LIBPROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastHex64ToBuffer(uint64 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer);
+
+// at least 22 bytes long
+inline char* FastIntToBuffer(int i, char* buffer) {
+  return (sizeof(i) == 4 ?
+          FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
+}
+inline char* FastUIntToBuffer(unsigned int i, char* buffer) {
+  return (sizeof(i) == 4 ?
+          FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
+}
+inline char* FastLongToBuffer(long i, char* buffer) {
+  return (sizeof(i) == 4 ?
+          FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
+}
+inline char* FastULongToBuffer(unsigned long i, char* buffer) {
+  return (sizeof(i) == 4 ?
+          FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
+}
+
+// ----------------------------------------------------------------------
+// FastInt32ToBufferLeft()
+// FastUInt32ToBufferLeft()
+// FastInt64ToBufferLeft()
+// FastUInt64ToBufferLeft()
+//
+// Like the Fast*ToBuffer() functions above, these are intended for speed.
+// Unlike the Fast*ToBuffer() functions, however, these functions write
+// their output to the beginning of the buffer (hence the name, as the
+// output is left-aligned).  The caller is responsible for ensuring that
+// the buffer has enough space to hold the output.
+//
+// Returns a pointer to the end of the string (i.e. the null character
+// terminating the string).
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT char* FastInt32ToBufferLeft(int32 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64 i, char* buffer);
+
+// Just define these in terms of the above.
+inline char* FastUInt32ToBuffer(uint32 i, char* buffer) {
+  FastUInt32ToBufferLeft(i, buffer);
+  return buffer;
+}
+inline char* FastUInt64ToBuffer(uint64 i, char* buffer) {
+  FastUInt64ToBufferLeft(i, buffer);
+  return buffer;
+}
+
+// ----------------------------------------------------------------------
+// SimpleItoa()
+//    Description: converts an integer to a string.
+//
+//    Return value: string
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string SimpleItoa(int i);
+LIBPROTOBUF_EXPORT string SimpleItoa(unsigned int i);
+LIBPROTOBUF_EXPORT string SimpleItoa(long i);
+LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long i);
+LIBPROTOBUF_EXPORT string SimpleItoa(long long i);
+LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long long i);
+
+// ----------------------------------------------------------------------
+// SimpleDtoa()
+// SimpleFtoa()
+// DoubleToBuffer()
+// FloatToBuffer()
+//    Description: converts a double or float to a string which, if
+//    passed to NoLocaleStrtod(), will produce the exact same original double
+//    (except in case of NaN; all NaNs are considered the same value).
+//    We try to keep the string short but it's not guaranteed to be as
+//    short as possible.
+//
+//    DoubleToBuffer() and FloatToBuffer() write the text to the given
+//    buffer and return it.  The buffer must be at least
+//    kDoubleToBufferSize bytes for doubles and kFloatToBufferSize
+//    bytes for floats.  kFastToBufferSize is also guaranteed to be large
+//    enough to hold either.
+//
+//    Return value: string
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string SimpleDtoa(double value);
+LIBPROTOBUF_EXPORT string SimpleFtoa(float value);
+
+LIBPROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer);
+LIBPROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer);
+
+// In practice, doubles should never need more than 24 bytes and floats
+// should never need more than 14 (including null terminators), but we
+// overestimate to be safe.
+static const int kDoubleToBufferSize = 32;
+static const int kFloatToBufferSize = 24;
+
+// ----------------------------------------------------------------------
+// NoLocaleStrtod()
+//   Exactly like strtod(), except it always behaves as if in the "C"
+//   locale (i.e. decimal points must be '.'s).
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT double NoLocaleStrtod(const char* text, char** endptr);
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
+
+
diff --git a/src/google/protobuf/stubs/strutil_unittest.cc b/src/google/protobuf/stubs/strutil_unittest.cc
new file mode 100644
index 0000000..58ffd32
--- /dev/null
+++ b/src/google/protobuf/stubs/strutil_unittest.cc
@@ -0,0 +1,68 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/strutil.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+// TODO(kenton):  Copy strutil tests from google3?
+
+TEST(StringUtilityTest, ImmuneToLocales) {
+  // Remember the old locale.
+  char* old_locale_cstr = setlocale(LC_NUMERIC, NULL);
+  ASSERT_TRUE(old_locale_cstr != NULL);
+  string old_locale = old_locale_cstr;
+
+  // Set the locale to "C".
+  ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != NULL);
+
+  EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL));
+  EXPECT_EQ("1.5", SimpleDtoa(1.5));
+  EXPECT_EQ("1.5", SimpleFtoa(1.5));
+
+  // Verify that the endptr is set correctly even if not all text was parsed.
+  const char* text = "1.5f";
+  char* endptr;
+  EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr));
+  EXPECT_EQ(3, endptr - text);
+
+  if (setlocale(LC_NUMERIC, "es_ES") == NULL &&
+      setlocale(LC_NUMERIC, "es_ES.utf8") == NULL) {
+    // Some systems may not have the desired locale available.
+    GOOGLE_LOG(WARNING)
+      << "Couldn't set locale to es_ES.  Skipping this test.";
+  } else {
+    EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL));
+    EXPECT_EQ("1.5", SimpleDtoa(1.5));
+    EXPECT_EQ("1.5", SimpleFtoa(1.5));
+    EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr));
+    EXPECT_EQ(3, endptr - text);
+  }
+
+  // Return to original locale.
+  setlocale(LC_NUMERIC, old_locale.c_str());
+}
+
+}  // anonymous namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/stubs/substitute.cc b/src/google/protobuf/stubs/substitute.cc
new file mode 100644
index 0000000..340be5e
--- /dev/null
+++ b/src/google/protobuf/stubs/substitute.cc
@@ -0,0 +1,120 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+namespace strings {
+
+using internal::SubstituteArg;
+
+// Returns the number of args in arg_array which were passed explicitly
+// to Substitute().
+static int CountSubstituteArgs(const SubstituteArg* const* args_array) {
+  int count = 0;
+  while (args_array[count] != NULL && args_array[count]->size() != -1) {
+    ++count;
+  }
+  return count;
+}
+
+string Substitute(
+    const char* format,
+    const SubstituteArg& arg0, const SubstituteArg& arg1,
+    const SubstituteArg& arg2, const SubstituteArg& arg3,
+    const SubstituteArg& arg4, const SubstituteArg& arg5,
+    const SubstituteArg& arg6, const SubstituteArg& arg7,
+    const SubstituteArg& arg8, const SubstituteArg& arg9) {
+  string result;
+  SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4,
+                                       arg5, arg6, arg7, arg8, arg9);
+  return result;
+}
+
+void SubstituteAndAppend(
+    string* output, const char* format,
+    const SubstituteArg& arg0, const SubstituteArg& arg1,
+    const SubstituteArg& arg2, const SubstituteArg& arg3,
+    const SubstituteArg& arg4, const SubstituteArg& arg5,
+    const SubstituteArg& arg6, const SubstituteArg& arg7,
+    const SubstituteArg& arg8, const SubstituteArg& arg9) {
+  const SubstituteArg* const args_array[] = {
+    &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, NULL
+  };
+
+  // Determine total size needed.
+  int size = 0;
+  for (int i = 0; format[i] != '\0'; i++) {
+    if (format[i] == '$') {
+      if (ascii_isdigit(format[i+1])) {
+        int index = format[i+1] - '0';
+        if (args_array[index]->size() == -1) {
+          GOOGLE_LOG(DFATAL)
+            << "strings::Substitute format string invalid: asked for \"$"
+            << index << "\", but only " << CountSubstituteArgs(args_array)
+            << " args were given.  Full format string was: \""
+            << CEscape(format) << "\".";
+          return;
+        }
+        size += args_array[index]->size();
+        ++i;  // Skip next char.
+      } else if (format[i+1] == '$') {
+        ++size;
+        ++i;  // Skip next char.
+      } else {
+        GOOGLE_LOG(DFATAL)
+          << "Invalid strings::Substitute() format string: \""
+          << CEscape(format) << "\".";
+        return;
+      }
+    } else {
+      ++size;
+    }
+  }
+
+  if (size == 0) return;
+
+  // Build the string.
+  int original_size = output->size();
+  STLStringResizeUninitialized(output, original_size + size);
+  char* target = string_as_array(output) + original_size;
+  for (int i = 0; format[i] != '\0'; i++) {
+    if (format[i] == '$') {
+      if (ascii_isdigit(format[i+1])) {
+        const SubstituteArg* src = args_array[format[i+1] - '0'];
+        memcpy(target, src->data(), src->size());
+        target += src->size();
+        ++i;  // Skip next char.
+      } else if (format[i+1] == '$') {
+        *target++ = '$';
+        ++i;  // Skip next char.
+      }
+    } else {
+      *target++ = format[i];
+    }
+  }
+
+  GOOGLE_DCHECK_EQ(target - output->data(), output->size());
+}
+
+}  // namespace strings
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/stubs/substitute.h b/src/google/protobuf/stubs/substitute.h
new file mode 100644
index 0000000..143e482
--- /dev/null
+++ b/src/google/protobuf/stubs/substitute.h
@@ -0,0 +1,156 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+// from google3/strings/substitute.h
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
+#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
+
+namespace google {
+namespace protobuf {
+namespace strings {
+
+// ----------------------------------------------------------------------
+// strings::Substitute()
+// strings::SubstituteAndAppend()
+//   Kind of like StringPrintf, but different.
+//
+//   Example:
+//     string GetMessage(string first_name, string last_name, int age) {
+//       return strings::Substitute("My name is $0 $1 and I am $2 years old.",
+//                                  first_name, last_name, age);
+//     }
+//
+//   Differences from StringPrintf:
+//   * The format string does not identify the types of arguments.
+//     Instead, the magic of C++ deals with this for us.  See below
+//     for a list of accepted types.
+//   * Substitutions in the format string are identified by a '$'
+//     followed by a digit.  So, you can use arguments out-of-order and
+//     use the same argument multiple times.
+//   * It's much faster than StringPrintf.
+//
+//   Supported types:
+//   * Strings (const char*, const string&)
+//     * Note that this means you do not have to add .c_str() to all of
+//       your strings.  In fact, you shouldn't; it will be slower.
+//   * int32, int64, uint32, uint64:  Formatted using SimpleItoa().
+//   * float, double:  Formatted using SimpleFtoa() and SimpleDtoa().
+//   * bool:  Printed as "true" or "false".
+//
+//   SubstituteAndAppend() is like Substitute() but appends the result to
+//   *output.  Example:
+//
+//     string str;
+//     strings::SubstituteAndAppend(&str,
+//                                  "My name is $0 $1 and I am $2 years old.",
+//                                  first_name, last_name, age);
+//
+//   Substitute() is significantly faster than StringPrintf().  For very
+//   large strings, it may be orders of magnitude faster.
+// ----------------------------------------------------------------------
+
+namespace internal {  // Implementation details.
+
+class SubstituteArg {
+ public:
+  inline SubstituteArg(const char* value)
+    : text_(value), size_(strlen(text_)) {}
+  inline SubstituteArg(const string& value)
+    : text_(value.data()), size_(value.size()) {}
+
+  // Indicates that no argument was given.
+  inline explicit SubstituteArg()
+    : text_(NULL), size_(-1) {}
+
+  // Primitives
+  // We don't overload for signed and unsigned char because if people are
+  // explicitly declaring their chars as signed or unsigned then they are
+  // probably actually using them as 8-bit integers and would probably
+  // prefer an integer representation.  But, we don't really know.  So, we
+  // make the caller decide what to do.
+  inline SubstituteArg(char value)
+    : text_(scratch_), size_(1) { scratch_[0] = value; }
+  inline SubstituteArg(short value)
+    : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+  inline SubstituteArg(unsigned short value)
+    : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+  inline SubstituteArg(int value)
+    : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+  inline SubstituteArg(unsigned int value)
+    : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+  inline SubstituteArg(long value)
+    : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {}
+  inline SubstituteArg(unsigned long value)
+    : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {}
+  inline SubstituteArg(long long value)
+    : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+  inline SubstituteArg(unsigned long long value)
+    : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+  inline SubstituteArg(float value)
+    : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {}
+  inline SubstituteArg(double value)
+    : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {}
+  inline SubstituteArg(bool value)
+    : text_(value ? "true" : "false"), size_(strlen(text_)) {}
+
+  inline const char* data() const { return text_; }
+  inline int size() const { return size_; }
+
+ private:
+  const char* text_;
+  int size_;
+  char scratch_[kFastToBufferSize];
+};
+
+}  // namespace internal
+
+LIBPROTOBUF_EXPORT string Substitute(
+  const char* format,
+  const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg9 = internal::SubstituteArg());
+
+LIBPROTOBUF_EXPORT void SubstituteAndAppend(
+  string* output, const char* format,
+  const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
+  const internal::SubstituteArg& arg9 = internal::SubstituteArg());
+
+}  // namespace strings
+}  // namespace protobuf
+}  // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
diff --git a/src/google/protobuf/test_util.cc b/src/google/protobuf/test_util.cc
new file mode 100644
index 0000000..1525e94
--- /dev/null
+++ b/src/google/protobuf/test_util.cc
@@ -0,0 +1,1912 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/message.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
+  message->set_optional_int32   (101);
+  message->set_optional_int64   (102);
+  message->set_optional_uint32  (103);
+  message->set_optional_uint64  (104);
+  message->set_optional_sint32  (105);
+  message->set_optional_sint64  (106);
+  message->set_optional_fixed32 (107);
+  message->set_optional_fixed64 (108);
+  message->set_optional_sfixed32(109);
+  message->set_optional_sfixed64(110);
+  message->set_optional_float   (111);
+  message->set_optional_double  (112);
+  message->set_optional_bool    (true);
+  message->set_optional_string  ("115");
+  message->set_optional_bytes   ("116");
+
+  message->mutable_optionalgroup           ()->set_a(117);
+  message->mutable_optional_nested_message ()->set_bb(118);
+  message->mutable_optional_foreign_message()->set_c(119);
+  message->mutable_optional_import_message ()->set_d(120);
+
+  message->set_optional_nested_enum (unittest::TestAllTypes::BAZ);
+  message->set_optional_foreign_enum(unittest::FOREIGN_BAZ      );
+  message->set_optional_import_enum (unittest_import::IMPORT_BAZ);
+
+  // 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->GetDescriptor()->FindFieldByName("optional_string_piece"),
+    "124");
+  message->GetReflection()->SetString(
+    message->GetDescriptor()->FindFieldByName("optional_cord"),
+    "125");
+
+  // -----------------------------------------------------------------
+
+  message->add_repeated_int32   (201);
+  message->add_repeated_int64   (202);
+  message->add_repeated_uint32  (203);
+  message->add_repeated_uint64  (204);
+  message->add_repeated_sint32  (205);
+  message->add_repeated_sint64  (206);
+  message->add_repeated_fixed32 (207);
+  message->add_repeated_fixed64 (208);
+  message->add_repeated_sfixed32(209);
+  message->add_repeated_sfixed64(210);
+  message->add_repeated_float   (211);
+  message->add_repeated_double  (212);
+  message->add_repeated_bool    (true);
+  message->add_repeated_string  ("215");
+  message->add_repeated_bytes   ("216");
+
+  message->add_repeatedgroup           ()->set_a(217);
+  message->add_repeated_nested_message ()->set_bb(218);
+  message->add_repeated_foreign_message()->set_c(219);
+  message->add_repeated_import_message ()->set_d(220);
+
+  message->add_repeated_nested_enum (unittest::TestAllTypes::BAR);
+  message->add_repeated_foreign_enum(unittest::FOREIGN_BAR      );
+  message->add_repeated_import_enum (unittest_import::IMPORT_BAR);
+
+  message->GetReflection()->AddString(
+    message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+    "224");
+  message->GetReflection()->AddString(
+    message->GetDescriptor()->FindFieldByName("repeated_cord"),
+    "225");
+
+  // Add a second one of each field.
+  message->add_repeated_int32   (301);
+  message->add_repeated_int64   (302);
+  message->add_repeated_uint32  (303);
+  message->add_repeated_uint64  (304);
+  message->add_repeated_sint32  (305);
+  message->add_repeated_sint64  (306);
+  message->add_repeated_fixed32 (307);
+  message->add_repeated_fixed64 (308);
+  message->add_repeated_sfixed32(309);
+  message->add_repeated_sfixed64(310);
+  message->add_repeated_float   (311);
+  message->add_repeated_double  (312);
+  message->add_repeated_bool    (false);
+  message->add_repeated_string  ("315");
+  message->add_repeated_bytes   ("316");
+
+  message->add_repeatedgroup           ()->set_a(317);
+  message->add_repeated_nested_message ()->set_bb(318);
+  message->add_repeated_foreign_message()->set_c(319);
+  message->add_repeated_import_message ()->set_d(320);
+
+  message->add_repeated_nested_enum (unittest::TestAllTypes::BAZ);
+  message->add_repeated_foreign_enum(unittest::FOREIGN_BAZ      );
+  message->add_repeated_import_enum (unittest_import::IMPORT_BAZ);
+
+  message->GetReflection()->AddString(
+    message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+    "324");
+  message->GetReflection()->AddString(
+    message->GetDescriptor()->FindFieldByName("repeated_cord"),
+    "325");
+
+  // -----------------------------------------------------------------
+
+  message->set_default_int32   (401);
+  message->set_default_int64   (402);
+  message->set_default_uint32  (403);
+  message->set_default_uint64  (404);
+  message->set_default_sint32  (405);
+  message->set_default_sint64  (406);
+  message->set_default_fixed32 (407);
+  message->set_default_fixed64 (408);
+  message->set_default_sfixed32(409);
+  message->set_default_sfixed64(410);
+  message->set_default_float   (411);
+  message->set_default_double  (412);
+  message->set_default_bool    (false);
+  message->set_default_string  ("415");
+  message->set_default_bytes   ("416");
+
+  message->set_default_nested_enum (unittest::TestAllTypes::FOO);
+  message->set_default_foreign_enum(unittest::FOREIGN_FOO      );
+  message->set_default_import_enum (unittest_import::IMPORT_FOO);
+
+  message->GetReflection()->SetString(
+    message->GetDescriptor()->FindFieldByName("default_string_piece"),
+    "424");
+  message->GetReflection()->SetString(
+    message->GetDescriptor()->FindFieldByName("default_cord"),
+    "425");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ModifyRepeatedFields(unittest::TestAllTypes* message) {
+  message->set_repeated_int32   (1, 501);
+  message->set_repeated_int64   (1, 502);
+  message->set_repeated_uint32  (1, 503);
+  message->set_repeated_uint64  (1, 504);
+  message->set_repeated_sint32  (1, 505);
+  message->set_repeated_sint64  (1, 506);
+  message->set_repeated_fixed32 (1, 507);
+  message->set_repeated_fixed64 (1, 508);
+  message->set_repeated_sfixed32(1, 509);
+  message->set_repeated_sfixed64(1, 510);
+  message->set_repeated_float   (1, 511);
+  message->set_repeated_double  (1, 512);
+  message->set_repeated_bool    (1, true);
+  message->set_repeated_string  (1, "515");
+  message->set_repeated_bytes   (1, "516");
+
+  message->mutable_repeatedgroup           (1)->set_a(517);
+  message->mutable_repeated_nested_message (1)->set_bb(518);
+  message->mutable_repeated_foreign_message(1)->set_c(519);
+  message->mutable_repeated_import_message (1)->set_d(520);
+
+  message->set_repeated_nested_enum (1, unittest::TestAllTypes::FOO);
+  message->set_repeated_foreign_enum(1, unittest::FOREIGN_FOO      );
+  message->set_repeated_import_enum (1, unittest_import::IMPORT_FOO);
+
+  message->GetReflection()->SetRepeatedString(
+    message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+    1, "424");
+  message->GetReflection()->SetRepeatedString(
+    message->GetDescriptor()->FindFieldByName("repeated_cord"),
+    1, "425");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
+  EXPECT_TRUE(message.has_optional_int32   ());
+  EXPECT_TRUE(message.has_optional_int64   ());
+  EXPECT_TRUE(message.has_optional_uint32  ());
+  EXPECT_TRUE(message.has_optional_uint64  ());
+  EXPECT_TRUE(message.has_optional_sint32  ());
+  EXPECT_TRUE(message.has_optional_sint64  ());
+  EXPECT_TRUE(message.has_optional_fixed32 ());
+  EXPECT_TRUE(message.has_optional_fixed64 ());
+  EXPECT_TRUE(message.has_optional_sfixed32());
+  EXPECT_TRUE(message.has_optional_sfixed64());
+  EXPECT_TRUE(message.has_optional_float   ());
+  EXPECT_TRUE(message.has_optional_double  ());
+  EXPECT_TRUE(message.has_optional_bool    ());
+  EXPECT_TRUE(message.has_optional_string  ());
+  EXPECT_TRUE(message.has_optional_bytes   ());
+
+  EXPECT_TRUE(message.has_optionalgroup           ());
+  EXPECT_TRUE(message.has_optional_nested_message ());
+  EXPECT_TRUE(message.has_optional_foreign_message());
+  EXPECT_TRUE(message.has_optional_import_message ());
+
+  EXPECT_TRUE(message.optionalgroup           ().has_a());
+  EXPECT_TRUE(message.optional_nested_message ().has_bb());
+  EXPECT_TRUE(message.optional_foreign_message().has_c());
+  EXPECT_TRUE(message.optional_import_message ().has_d());
+
+  EXPECT_TRUE(message.has_optional_nested_enum ());
+  EXPECT_TRUE(message.has_optional_foreign_enum());
+  EXPECT_TRUE(message.has_optional_import_enum ());
+
+  EXPECT_TRUE(message.has_optional_string_piece());
+  EXPECT_TRUE(message.has_optional_cord());
+
+  EXPECT_EQ(101  , message.optional_int32   ());
+  EXPECT_EQ(102  , message.optional_int64   ());
+  EXPECT_EQ(103  , message.optional_uint32  ());
+  EXPECT_EQ(104  , message.optional_uint64  ());
+  EXPECT_EQ(105  , message.optional_sint32  ());
+  EXPECT_EQ(106  , message.optional_sint64  ());
+  EXPECT_EQ(107  , message.optional_fixed32 ());
+  EXPECT_EQ(108  , message.optional_fixed64 ());
+  EXPECT_EQ(109  , message.optional_sfixed32());
+  EXPECT_EQ(110  , message.optional_sfixed64());
+  EXPECT_EQ(111  , message.optional_float   ());
+  EXPECT_EQ(112  , message.optional_double  ());
+  EXPECT_EQ(true , message.optional_bool    ());
+  EXPECT_EQ("115", message.optional_string  ());
+  EXPECT_EQ("116", message.optional_bytes   ());
+
+  EXPECT_EQ(117, message.optionalgroup           ().a());
+  EXPECT_EQ(118, message.optional_nested_message ().bb());
+  EXPECT_EQ(119, message.optional_foreign_message().c());
+  EXPECT_EQ(120, message.optional_import_message ().d());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAZ, message.optional_nested_enum ());
+  EXPECT_EQ(unittest::FOREIGN_BAZ      , message.optional_foreign_enum());
+  EXPECT_EQ(unittest_import::IMPORT_BAZ, message.optional_import_enum ());
+
+
+  // -----------------------------------------------------------------
+
+  ASSERT_EQ(2, message.repeated_int32_size   ());
+  ASSERT_EQ(2, message.repeated_int64_size   ());
+  ASSERT_EQ(2, message.repeated_uint32_size  ());
+  ASSERT_EQ(2, message.repeated_uint64_size  ());
+  ASSERT_EQ(2, message.repeated_sint32_size  ());
+  ASSERT_EQ(2, message.repeated_sint64_size  ());
+  ASSERT_EQ(2, message.repeated_fixed32_size ());
+  ASSERT_EQ(2, message.repeated_fixed64_size ());
+  ASSERT_EQ(2, message.repeated_sfixed32_size());
+  ASSERT_EQ(2, message.repeated_sfixed64_size());
+  ASSERT_EQ(2, message.repeated_float_size   ());
+  ASSERT_EQ(2, message.repeated_double_size  ());
+  ASSERT_EQ(2, message.repeated_bool_size    ());
+  ASSERT_EQ(2, message.repeated_string_size  ());
+  ASSERT_EQ(2, message.repeated_bytes_size   ());
+
+  ASSERT_EQ(2, message.repeatedgroup_size           ());
+  ASSERT_EQ(2, message.repeated_nested_message_size ());
+  ASSERT_EQ(2, message.repeated_foreign_message_size());
+  ASSERT_EQ(2, message.repeated_import_message_size ());
+  ASSERT_EQ(2, message.repeated_nested_enum_size    ());
+  ASSERT_EQ(2, message.repeated_foreign_enum_size   ());
+  ASSERT_EQ(2, message.repeated_import_enum_size    ());
+
+  ASSERT_EQ(2, message.repeated_string_piece_size());
+  ASSERT_EQ(2, message.repeated_cord_size());
+
+  EXPECT_EQ(201  , message.repeated_int32   (0));
+  EXPECT_EQ(202  , message.repeated_int64   (0));
+  EXPECT_EQ(203  , message.repeated_uint32  (0));
+  EXPECT_EQ(204  , message.repeated_uint64  (0));
+  EXPECT_EQ(205  , message.repeated_sint32  (0));
+  EXPECT_EQ(206  , message.repeated_sint64  (0));
+  EXPECT_EQ(207  , message.repeated_fixed32 (0));
+  EXPECT_EQ(208  , message.repeated_fixed64 (0));
+  EXPECT_EQ(209  , message.repeated_sfixed32(0));
+  EXPECT_EQ(210  , message.repeated_sfixed64(0));
+  EXPECT_EQ(211  , message.repeated_float   (0));
+  EXPECT_EQ(212  , message.repeated_double  (0));
+  EXPECT_EQ(true , message.repeated_bool    (0));
+  EXPECT_EQ("215", message.repeated_string  (0));
+  EXPECT_EQ("216", message.repeated_bytes   (0));
+
+  EXPECT_EQ(217, message.repeatedgroup           (0).a());
+  EXPECT_EQ(218, message.repeated_nested_message (0).bb());
+  EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+  EXPECT_EQ(220, message.repeated_import_message (0).d());
+
+
+  EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0));
+  EXPECT_EQ(unittest::FOREIGN_BAR      , message.repeated_foreign_enum(0));
+  EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0));
+
+  EXPECT_EQ(301  , message.repeated_int32   (1));
+  EXPECT_EQ(302  , message.repeated_int64   (1));
+  EXPECT_EQ(303  , message.repeated_uint32  (1));
+  EXPECT_EQ(304  , message.repeated_uint64  (1));
+  EXPECT_EQ(305  , message.repeated_sint32  (1));
+  EXPECT_EQ(306  , message.repeated_sint64  (1));
+  EXPECT_EQ(307  , message.repeated_fixed32 (1));
+  EXPECT_EQ(308  , message.repeated_fixed64 (1));
+  EXPECT_EQ(309  , message.repeated_sfixed32(1));
+  EXPECT_EQ(310  , message.repeated_sfixed64(1));
+  EXPECT_EQ(311  , message.repeated_float   (1));
+  EXPECT_EQ(312  , message.repeated_double  (1));
+  EXPECT_EQ(false, message.repeated_bool    (1));
+  EXPECT_EQ("315", message.repeated_string  (1));
+  EXPECT_EQ("316", message.repeated_bytes   (1));
+
+  EXPECT_EQ(317, message.repeatedgroup           (1).a());
+  EXPECT_EQ(318, message.repeated_nested_message (1).bb());
+  EXPECT_EQ(319, message.repeated_foreign_message(1).c());
+  EXPECT_EQ(320, message.repeated_import_message (1).d());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (1));
+  EXPECT_EQ(unittest::FOREIGN_BAZ      , message.repeated_foreign_enum(1));
+  EXPECT_EQ(unittest_import::IMPORT_BAZ, message.repeated_import_enum (1));
+
+
+  // -----------------------------------------------------------------
+
+  EXPECT_TRUE(message.has_default_int32   ());
+  EXPECT_TRUE(message.has_default_int64   ());
+  EXPECT_TRUE(message.has_default_uint32  ());
+  EXPECT_TRUE(message.has_default_uint64  ());
+  EXPECT_TRUE(message.has_default_sint32  ());
+  EXPECT_TRUE(message.has_default_sint64  ());
+  EXPECT_TRUE(message.has_default_fixed32 ());
+  EXPECT_TRUE(message.has_default_fixed64 ());
+  EXPECT_TRUE(message.has_default_sfixed32());
+  EXPECT_TRUE(message.has_default_sfixed64());
+  EXPECT_TRUE(message.has_default_float   ());
+  EXPECT_TRUE(message.has_default_double  ());
+  EXPECT_TRUE(message.has_default_bool    ());
+  EXPECT_TRUE(message.has_default_string  ());
+  EXPECT_TRUE(message.has_default_bytes   ());
+
+  EXPECT_TRUE(message.has_default_nested_enum ());
+  EXPECT_TRUE(message.has_default_foreign_enum());
+  EXPECT_TRUE(message.has_default_import_enum ());
+
+
+  EXPECT_EQ(401  , message.default_int32   ());
+  EXPECT_EQ(402  , message.default_int64   ());
+  EXPECT_EQ(403  , message.default_uint32  ());
+  EXPECT_EQ(404  , message.default_uint64  ());
+  EXPECT_EQ(405  , message.default_sint32  ());
+  EXPECT_EQ(406  , message.default_sint64  ());
+  EXPECT_EQ(407  , message.default_fixed32 ());
+  EXPECT_EQ(408  , message.default_fixed64 ());
+  EXPECT_EQ(409  , message.default_sfixed32());
+  EXPECT_EQ(410  , message.default_sfixed64());
+  EXPECT_EQ(411  , message.default_float   ());
+  EXPECT_EQ(412  , message.default_double  ());
+  EXPECT_EQ(false, message.default_bool    ());
+  EXPECT_EQ("415", message.default_string  ());
+  EXPECT_EQ("416", message.default_bytes   ());
+
+  EXPECT_EQ(unittest::TestAllTypes::FOO, message.default_nested_enum ());
+  EXPECT_EQ(unittest::FOREIGN_FOO      , message.default_foreign_enum());
+  EXPECT_EQ(unittest_import::IMPORT_FOO, message.default_import_enum ());
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectClear(const unittest::TestAllTypes& message) {
+  // has_blah() should initially be false for all optional fields.
+  EXPECT_FALSE(message.has_optional_int32   ());
+  EXPECT_FALSE(message.has_optional_int64   ());
+  EXPECT_FALSE(message.has_optional_uint32  ());
+  EXPECT_FALSE(message.has_optional_uint64  ());
+  EXPECT_FALSE(message.has_optional_sint32  ());
+  EXPECT_FALSE(message.has_optional_sint64  ());
+  EXPECT_FALSE(message.has_optional_fixed32 ());
+  EXPECT_FALSE(message.has_optional_fixed64 ());
+  EXPECT_FALSE(message.has_optional_sfixed32());
+  EXPECT_FALSE(message.has_optional_sfixed64());
+  EXPECT_FALSE(message.has_optional_float   ());
+  EXPECT_FALSE(message.has_optional_double  ());
+  EXPECT_FALSE(message.has_optional_bool    ());
+  EXPECT_FALSE(message.has_optional_string  ());
+  EXPECT_FALSE(message.has_optional_bytes   ());
+
+  EXPECT_FALSE(message.has_optionalgroup           ());
+  EXPECT_FALSE(message.has_optional_nested_message ());
+  EXPECT_FALSE(message.has_optional_foreign_message());
+  EXPECT_FALSE(message.has_optional_import_message ());
+
+  EXPECT_FALSE(message.has_optional_nested_enum ());
+  EXPECT_FALSE(message.has_optional_foreign_enum());
+  EXPECT_FALSE(message.has_optional_import_enum ());
+
+  EXPECT_FALSE(message.has_optional_string_piece());
+  EXPECT_FALSE(message.has_optional_cord());
+
+  // Optional fields without defaults are set to zero or something like it.
+  EXPECT_EQ(0    , message.optional_int32   ());
+  EXPECT_EQ(0    , message.optional_int64   ());
+  EXPECT_EQ(0    , message.optional_uint32  ());
+  EXPECT_EQ(0    , message.optional_uint64  ());
+  EXPECT_EQ(0    , message.optional_sint32  ());
+  EXPECT_EQ(0    , message.optional_sint64  ());
+  EXPECT_EQ(0    , message.optional_fixed32 ());
+  EXPECT_EQ(0    , message.optional_fixed64 ());
+  EXPECT_EQ(0    , message.optional_sfixed32());
+  EXPECT_EQ(0    , message.optional_sfixed64());
+  EXPECT_EQ(0    , message.optional_float   ());
+  EXPECT_EQ(0    , message.optional_double  ());
+  EXPECT_EQ(false, message.optional_bool    ());
+  EXPECT_EQ(""   , message.optional_string  ());
+  EXPECT_EQ(""   , message.optional_bytes   ());
+
+  // Embedded messages should also be clear.
+  EXPECT_FALSE(message.optionalgroup           ().has_a());
+  EXPECT_FALSE(message.optional_nested_message ().has_bb());
+  EXPECT_FALSE(message.optional_foreign_message().has_c());
+  EXPECT_FALSE(message.optional_import_message ().has_d());
+
+  EXPECT_EQ(0, message.optionalgroup           ().a());
+  EXPECT_EQ(0, message.optional_nested_message ().bb());
+  EXPECT_EQ(0, message.optional_foreign_message().c());
+  EXPECT_EQ(0, message.optional_import_message ().d());
+
+  // Enums without defaults are set to the first value in the enum.
+  EXPECT_EQ(unittest::TestAllTypes::FOO, message.optional_nested_enum ());
+  EXPECT_EQ(unittest::FOREIGN_FOO      , message.optional_foreign_enum());
+  EXPECT_EQ(unittest_import::IMPORT_FOO, message.optional_import_enum ());
+
+
+  // Repeated fields are empty.
+  EXPECT_EQ(0, message.repeated_int32_size   ());
+  EXPECT_EQ(0, message.repeated_int64_size   ());
+  EXPECT_EQ(0, message.repeated_uint32_size  ());
+  EXPECT_EQ(0, message.repeated_uint64_size  ());
+  EXPECT_EQ(0, message.repeated_sint32_size  ());
+  EXPECT_EQ(0, message.repeated_sint64_size  ());
+  EXPECT_EQ(0, message.repeated_fixed32_size ());
+  EXPECT_EQ(0, message.repeated_fixed64_size ());
+  EXPECT_EQ(0, message.repeated_sfixed32_size());
+  EXPECT_EQ(0, message.repeated_sfixed64_size());
+  EXPECT_EQ(0, message.repeated_float_size   ());
+  EXPECT_EQ(0, message.repeated_double_size  ());
+  EXPECT_EQ(0, message.repeated_bool_size    ());
+  EXPECT_EQ(0, message.repeated_string_size  ());
+  EXPECT_EQ(0, message.repeated_bytes_size   ());
+
+  EXPECT_EQ(0, message.repeatedgroup_size           ());
+  EXPECT_EQ(0, message.repeated_nested_message_size ());
+  EXPECT_EQ(0, message.repeated_foreign_message_size());
+  EXPECT_EQ(0, message.repeated_import_message_size ());
+  EXPECT_EQ(0, message.repeated_nested_enum_size    ());
+  EXPECT_EQ(0, message.repeated_foreign_enum_size   ());
+  EXPECT_EQ(0, message.repeated_import_enum_size    ());
+
+  EXPECT_EQ(0, message.repeated_string_piece_size());
+  EXPECT_EQ(0, message.repeated_cord_size());
+
+  // has_blah() should also be false for all default fields.
+  EXPECT_FALSE(message.has_default_int32   ());
+  EXPECT_FALSE(message.has_default_int64   ());
+  EXPECT_FALSE(message.has_default_uint32  ());
+  EXPECT_FALSE(message.has_default_uint64  ());
+  EXPECT_FALSE(message.has_default_sint32  ());
+  EXPECT_FALSE(message.has_default_sint64  ());
+  EXPECT_FALSE(message.has_default_fixed32 ());
+  EXPECT_FALSE(message.has_default_fixed64 ());
+  EXPECT_FALSE(message.has_default_sfixed32());
+  EXPECT_FALSE(message.has_default_sfixed64());
+  EXPECT_FALSE(message.has_default_float   ());
+  EXPECT_FALSE(message.has_default_double  ());
+  EXPECT_FALSE(message.has_default_bool    ());
+  EXPECT_FALSE(message.has_default_string  ());
+  EXPECT_FALSE(message.has_default_bytes   ());
+
+  EXPECT_FALSE(message.has_default_nested_enum ());
+  EXPECT_FALSE(message.has_default_foreign_enum());
+  EXPECT_FALSE(message.has_default_import_enum ());
+
+
+  // Fields with defaults have their default values (duh).
+  EXPECT_EQ( 41    , message.default_int32   ());
+  EXPECT_EQ( 42    , message.default_int64   ());
+  EXPECT_EQ( 43    , message.default_uint32  ());
+  EXPECT_EQ( 44    , message.default_uint64  ());
+  EXPECT_EQ(-45    , message.default_sint32  ());
+  EXPECT_EQ( 46    , message.default_sint64  ());
+  EXPECT_EQ( 47    , message.default_fixed32 ());
+  EXPECT_EQ( 48    , message.default_fixed64 ());
+  EXPECT_EQ( 49    , message.default_sfixed32());
+  EXPECT_EQ(-50    , message.default_sfixed64());
+  EXPECT_EQ( 51.5  , message.default_float   ());
+  EXPECT_EQ( 52e3  , message.default_double  ());
+  EXPECT_EQ(true   , message.default_bool    ());
+  EXPECT_EQ("hello", message.default_string  ());
+  EXPECT_EQ("world", message.default_bytes   ());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAR, message.default_nested_enum ());
+  EXPECT_EQ(unittest::FOREIGN_BAR      , message.default_foreign_enum());
+  EXPECT_EQ(unittest_import::IMPORT_BAR, message.default_import_enum ());
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectRepeatedFieldsModified(
+    const unittest::TestAllTypes& message) {
+  // ModifyRepeatedFields only sets the second repeated element of each
+  // field.  In addition to verifying this, we also verify that the first
+  // element and size were *not* modified.
+  ASSERT_EQ(2, message.repeated_int32_size   ());
+  ASSERT_EQ(2, message.repeated_int64_size   ());
+  ASSERT_EQ(2, message.repeated_uint32_size  ());
+  ASSERT_EQ(2, message.repeated_uint64_size  ());
+  ASSERT_EQ(2, message.repeated_sint32_size  ());
+  ASSERT_EQ(2, message.repeated_sint64_size  ());
+  ASSERT_EQ(2, message.repeated_fixed32_size ());
+  ASSERT_EQ(2, message.repeated_fixed64_size ());
+  ASSERT_EQ(2, message.repeated_sfixed32_size());
+  ASSERT_EQ(2, message.repeated_sfixed64_size());
+  ASSERT_EQ(2, message.repeated_float_size   ());
+  ASSERT_EQ(2, message.repeated_double_size  ());
+  ASSERT_EQ(2, message.repeated_bool_size    ());
+  ASSERT_EQ(2, message.repeated_string_size  ());
+  ASSERT_EQ(2, message.repeated_bytes_size   ());
+
+  ASSERT_EQ(2, message.repeatedgroup_size           ());
+  ASSERT_EQ(2, message.repeated_nested_message_size ());
+  ASSERT_EQ(2, message.repeated_foreign_message_size());
+  ASSERT_EQ(2, message.repeated_import_message_size ());
+  ASSERT_EQ(2, message.repeated_nested_enum_size    ());
+  ASSERT_EQ(2, message.repeated_foreign_enum_size   ());
+  ASSERT_EQ(2, message.repeated_import_enum_size    ());
+
+  ASSERT_EQ(2, message.repeated_string_piece_size());
+  ASSERT_EQ(2, message.repeated_cord_size());
+
+  EXPECT_EQ(201  , message.repeated_int32   (0));
+  EXPECT_EQ(202  , message.repeated_int64   (0));
+  EXPECT_EQ(203  , message.repeated_uint32  (0));
+  EXPECT_EQ(204  , message.repeated_uint64  (0));
+  EXPECT_EQ(205  , message.repeated_sint32  (0));
+  EXPECT_EQ(206  , message.repeated_sint64  (0));
+  EXPECT_EQ(207  , message.repeated_fixed32 (0));
+  EXPECT_EQ(208  , message.repeated_fixed64 (0));
+  EXPECT_EQ(209  , message.repeated_sfixed32(0));
+  EXPECT_EQ(210  , message.repeated_sfixed64(0));
+  EXPECT_EQ(211  , message.repeated_float   (0));
+  EXPECT_EQ(212  , message.repeated_double  (0));
+  EXPECT_EQ(true , message.repeated_bool    (0));
+  EXPECT_EQ("215", message.repeated_string  (0));
+  EXPECT_EQ("216", message.repeated_bytes   (0));
+
+  EXPECT_EQ(217, message.repeatedgroup           (0).a());
+  EXPECT_EQ(218, message.repeated_nested_message (0).bb());
+  EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+  EXPECT_EQ(220, message.repeated_import_message (0).d());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0));
+  EXPECT_EQ(unittest::FOREIGN_BAR      , message.repeated_foreign_enum(0));
+  EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0));
+
+
+  // Actually verify the second (modified) elements now.
+  EXPECT_EQ(501  , message.repeated_int32   (1));
+  EXPECT_EQ(502  , message.repeated_int64   (1));
+  EXPECT_EQ(503  , message.repeated_uint32  (1));
+  EXPECT_EQ(504  , message.repeated_uint64  (1));
+  EXPECT_EQ(505  , message.repeated_sint32  (1));
+  EXPECT_EQ(506  , message.repeated_sint64  (1));
+  EXPECT_EQ(507  , message.repeated_fixed32 (1));
+  EXPECT_EQ(508  , message.repeated_fixed64 (1));
+  EXPECT_EQ(509  , message.repeated_sfixed32(1));
+  EXPECT_EQ(510  , message.repeated_sfixed64(1));
+  EXPECT_EQ(511  , message.repeated_float   (1));
+  EXPECT_EQ(512  , message.repeated_double  (1));
+  EXPECT_EQ(true , message.repeated_bool    (1));
+  EXPECT_EQ("515", message.repeated_string  (1));
+  EXPECT_EQ("516", message.repeated_bytes   (1));
+
+  EXPECT_EQ(517, message.repeatedgroup           (1).a());
+  EXPECT_EQ(518, message.repeated_nested_message (1).bb());
+  EXPECT_EQ(519, message.repeated_foreign_message(1).c());
+  EXPECT_EQ(520, message.repeated_import_message (1).d());
+
+  EXPECT_EQ(unittest::TestAllTypes::FOO, message.repeated_nested_enum (1));
+  EXPECT_EQ(unittest::FOREIGN_FOO      , message.repeated_foreign_enum(1));
+  EXPECT_EQ(unittest_import::IMPORT_FOO, message.repeated_import_enum (1));
+
+}
+
+// ===================================================================
+// Extensions
+//
+// All this code is exactly equivalent to the above code except that it's
+// manipulating extension fields instead of normal ones.
+//
+// I gave up on the 80-char limit here.  Sorry.
+
+void TestUtil::SetAllExtensions(unittest::TestAllExtensions* message) {
+  message->SetExtension(unittest::optional_int32_extension   , 101);
+  message->SetExtension(unittest::optional_int64_extension   , 102);
+  message->SetExtension(unittest::optional_uint32_extension  , 103);
+  message->SetExtension(unittest::optional_uint64_extension  , 104);
+  message->SetExtension(unittest::optional_sint32_extension  , 105);
+  message->SetExtension(unittest::optional_sint64_extension  , 106);
+  message->SetExtension(unittest::optional_fixed32_extension , 107);
+  message->SetExtension(unittest::optional_fixed64_extension , 108);
+  message->SetExtension(unittest::optional_sfixed32_extension, 109);
+  message->SetExtension(unittest::optional_sfixed64_extension, 110);
+  message->SetExtension(unittest::optional_float_extension   , 111);
+  message->SetExtension(unittest::optional_double_extension  , 112);
+  message->SetExtension(unittest::optional_bool_extension    , true);
+  message->SetExtension(unittest::optional_string_extension  , "115");
+  message->SetExtension(unittest::optional_bytes_extension   , "116");
+
+  message->MutableExtension(unittest::optionalgroup_extension           )->set_a(117);
+  message->MutableExtension(unittest::optional_nested_message_extension )->set_bb(118);
+  message->MutableExtension(unittest::optional_foreign_message_extension)->set_c(119);
+  message->MutableExtension(unittest::optional_import_message_extension )->set_d(120);
+
+  message->SetExtension(unittest::optional_nested_enum_extension , unittest::TestAllTypes::BAZ);
+  message->SetExtension(unittest::optional_foreign_enum_extension, unittest::FOREIGN_BAZ      );
+  message->SetExtension(unittest::optional_import_enum_extension , unittest_import::IMPORT_BAZ);
+
+  message->SetExtension(unittest::optional_string_piece_extension, "124");
+  message->SetExtension(unittest::optional_cord_extension, "125");
+
+  // -----------------------------------------------------------------
+
+  message->AddExtension(unittest::repeated_int32_extension   , 201);
+  message->AddExtension(unittest::repeated_int64_extension   , 202);
+  message->AddExtension(unittest::repeated_uint32_extension  , 203);
+  message->AddExtension(unittest::repeated_uint64_extension  , 204);
+  message->AddExtension(unittest::repeated_sint32_extension  , 205);
+  message->AddExtension(unittest::repeated_sint64_extension  , 206);
+  message->AddExtension(unittest::repeated_fixed32_extension , 207);
+  message->AddExtension(unittest::repeated_fixed64_extension , 208);
+  message->AddExtension(unittest::repeated_sfixed32_extension, 209);
+  message->AddExtension(unittest::repeated_sfixed64_extension, 210);
+  message->AddExtension(unittest::repeated_float_extension   , 211);
+  message->AddExtension(unittest::repeated_double_extension  , 212);
+  message->AddExtension(unittest::repeated_bool_extension    , true);
+  message->AddExtension(unittest::repeated_string_extension  , "215");
+  message->AddExtension(unittest::repeated_bytes_extension   , "216");
+
+  message->AddExtension(unittest::repeatedgroup_extension           )->set_a(217);
+  message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(218);
+  message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(219);
+  message->AddExtension(unittest::repeated_import_message_extension )->set_d(220);
+
+  message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAR);
+  message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAR      );
+  message->AddExtension(unittest::repeated_import_enum_extension , unittest_import::IMPORT_BAR);
+
+  message->AddExtension(unittest::repeated_string_piece_extension, "224");
+  message->AddExtension(unittest::repeated_cord_extension, "225");
+
+  // Add a second one of each field.
+  message->AddExtension(unittest::repeated_int32_extension   , 301);
+  message->AddExtension(unittest::repeated_int64_extension   , 302);
+  message->AddExtension(unittest::repeated_uint32_extension  , 303);
+  message->AddExtension(unittest::repeated_uint64_extension  , 304);
+  message->AddExtension(unittest::repeated_sint32_extension  , 305);
+  message->AddExtension(unittest::repeated_sint64_extension  , 306);
+  message->AddExtension(unittest::repeated_fixed32_extension , 307);
+  message->AddExtension(unittest::repeated_fixed64_extension , 308);
+  message->AddExtension(unittest::repeated_sfixed32_extension, 309);
+  message->AddExtension(unittest::repeated_sfixed64_extension, 310);
+  message->AddExtension(unittest::repeated_float_extension   , 311);
+  message->AddExtension(unittest::repeated_double_extension  , 312);
+  message->AddExtension(unittest::repeated_bool_extension    , false);
+  message->AddExtension(unittest::repeated_string_extension  , "315");
+  message->AddExtension(unittest::repeated_bytes_extension   , "316");
+
+  message->AddExtension(unittest::repeatedgroup_extension           )->set_a(317);
+  message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(318);
+  message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(319);
+  message->AddExtension(unittest::repeated_import_message_extension )->set_d(320);
+
+  message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAZ);
+  message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAZ      );
+  message->AddExtension(unittest::repeated_import_enum_extension , unittest_import::IMPORT_BAZ);
+
+  message->AddExtension(unittest::repeated_string_piece_extension, "324");
+  message->AddExtension(unittest::repeated_cord_extension, "325");
+
+  // -----------------------------------------------------------------
+
+  message->SetExtension(unittest::default_int32_extension   , 401);
+  message->SetExtension(unittest::default_int64_extension   , 402);
+  message->SetExtension(unittest::default_uint32_extension  , 403);
+  message->SetExtension(unittest::default_uint64_extension  , 404);
+  message->SetExtension(unittest::default_sint32_extension  , 405);
+  message->SetExtension(unittest::default_sint64_extension  , 406);
+  message->SetExtension(unittest::default_fixed32_extension , 407);
+  message->SetExtension(unittest::default_fixed64_extension , 408);
+  message->SetExtension(unittest::default_sfixed32_extension, 409);
+  message->SetExtension(unittest::default_sfixed64_extension, 410);
+  message->SetExtension(unittest::default_float_extension   , 411);
+  message->SetExtension(unittest::default_double_extension  , 412);
+  message->SetExtension(unittest::default_bool_extension    , false);
+  message->SetExtension(unittest::default_string_extension  , "415");
+  message->SetExtension(unittest::default_bytes_extension   , "416");
+
+  message->SetExtension(unittest::default_nested_enum_extension , unittest::TestAllTypes::FOO);
+  message->SetExtension(unittest::default_foreign_enum_extension, unittest::FOREIGN_FOO      );
+  message->SetExtension(unittest::default_import_enum_extension , unittest_import::IMPORT_FOO);
+
+  message->SetExtension(unittest::default_string_piece_extension, "424");
+  message->SetExtension(unittest::default_cord_extension, "425");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::SetAllFieldsAndExtensions(
+    unittest::TestFieldOrderings* message) {
+  GOOGLE_CHECK(message);
+  message->set_my_int(1);
+  message->set_my_string("foo");
+  message->set_my_float(1.0);
+  message->SetExtension(unittest::my_extension_int, 23);
+  message->SetExtension(unittest::my_extension_string, "bar");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ModifyRepeatedExtensions(unittest::TestAllExtensions* message) {
+  message->SetExtension(unittest::repeated_int32_extension   , 1, 501);
+  message->SetExtension(unittest::repeated_int64_extension   , 1, 502);
+  message->SetExtension(unittest::repeated_uint32_extension  , 1, 503);
+  message->SetExtension(unittest::repeated_uint64_extension  , 1, 504);
+  message->SetExtension(unittest::repeated_sint32_extension  , 1, 505);
+  message->SetExtension(unittest::repeated_sint64_extension  , 1, 506);
+  message->SetExtension(unittest::repeated_fixed32_extension , 1, 507);
+  message->SetExtension(unittest::repeated_fixed64_extension , 1, 508);
+  message->SetExtension(unittest::repeated_sfixed32_extension, 1, 509);
+  message->SetExtension(unittest::repeated_sfixed64_extension, 1, 510);
+  message->SetExtension(unittest::repeated_float_extension   , 1, 511);
+  message->SetExtension(unittest::repeated_double_extension  , 1, 512);
+  message->SetExtension(unittest::repeated_bool_extension    , 1, true);
+  message->SetExtension(unittest::repeated_string_extension  , 1, "515");
+  message->SetExtension(unittest::repeated_bytes_extension   , 1, "516");
+
+  message->MutableExtension(unittest::repeatedgroup_extension           , 1)->set_a(517);
+  message->MutableExtension(unittest::repeated_nested_message_extension , 1)->set_bb(518);
+  message->MutableExtension(unittest::repeated_foreign_message_extension, 1)->set_c(519);
+  message->MutableExtension(unittest::repeated_import_message_extension , 1)->set_d(520);
+
+  message->SetExtension(unittest::repeated_nested_enum_extension , 1, unittest::TestAllTypes::FOO);
+  message->SetExtension(unittest::repeated_foreign_enum_extension, 1, unittest::FOREIGN_FOO      );
+  message->SetExtension(unittest::repeated_import_enum_extension , 1, unittest_import::IMPORT_FOO);
+
+  message->SetExtension(unittest::repeated_string_piece_extension, 1, "524");
+  message->SetExtension(unittest::repeated_cord_extension, 1, "525");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectAllExtensionsSet(
+    const unittest::TestAllExtensions& message) {
+  EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension   ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension   ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension   ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension    ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension   ));
+
+  EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension           ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension ));
+
+  EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension           ).has_a());
+  EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb());
+  EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension).has_c());
+  EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension ).has_d());
+
+  EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_import_enum_extension ));
+
+  EXPECT_TRUE(message.HasExtension(unittest::optional_string_piece_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_cord_extension));
+
+  EXPECT_EQ(101  , message.GetExtension(unittest::optional_int32_extension   ));
+  EXPECT_EQ(102  , message.GetExtension(unittest::optional_int64_extension   ));
+  EXPECT_EQ(103  , message.GetExtension(unittest::optional_uint32_extension  ));
+  EXPECT_EQ(104  , message.GetExtension(unittest::optional_uint64_extension  ));
+  EXPECT_EQ(105  , message.GetExtension(unittest::optional_sint32_extension  ));
+  EXPECT_EQ(106  , message.GetExtension(unittest::optional_sint64_extension  ));
+  EXPECT_EQ(107  , message.GetExtension(unittest::optional_fixed32_extension ));
+  EXPECT_EQ(108  , message.GetExtension(unittest::optional_fixed64_extension ));
+  EXPECT_EQ(109  , message.GetExtension(unittest::optional_sfixed32_extension));
+  EXPECT_EQ(110  , message.GetExtension(unittest::optional_sfixed64_extension));
+  EXPECT_EQ(111  , message.GetExtension(unittest::optional_float_extension   ));
+  EXPECT_EQ(112  , message.GetExtension(unittest::optional_double_extension  ));
+  EXPECT_EQ(true , message.GetExtension(unittest::optional_bool_extension    ));
+  EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension  ));
+  EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension   ));
+
+  EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension           ).a());
+  EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension ).bb());
+  EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension).c());
+  EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension ).d());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::optional_nested_enum_extension ));
+  EXPECT_EQ(unittest::FOREIGN_BAZ      , message.GetExtension(unittest::optional_foreign_enum_extension));
+  EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::optional_import_enum_extension ));
+
+  EXPECT_EQ("124", message.GetExtension(unittest::optional_string_piece_extension));
+  EXPECT_EQ("125", message.GetExtension(unittest::optional_cord_extension));
+
+  // -----------------------------------------------------------------
+
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension   ));
+
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension           ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension    ));
+
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension));
+
+  EXPECT_EQ(201  , message.GetExtension(unittest::repeated_int32_extension   , 0));
+  EXPECT_EQ(202  , message.GetExtension(unittest::repeated_int64_extension   , 0));
+  EXPECT_EQ(203  , message.GetExtension(unittest::repeated_uint32_extension  , 0));
+  EXPECT_EQ(204  , message.GetExtension(unittest::repeated_uint64_extension  , 0));
+  EXPECT_EQ(205  , message.GetExtension(unittest::repeated_sint32_extension  , 0));
+  EXPECT_EQ(206  , message.GetExtension(unittest::repeated_sint64_extension  , 0));
+  EXPECT_EQ(207  , message.GetExtension(unittest::repeated_fixed32_extension , 0));
+  EXPECT_EQ(208  , message.GetExtension(unittest::repeated_fixed64_extension , 0));
+  EXPECT_EQ(209  , message.GetExtension(unittest::repeated_sfixed32_extension, 0));
+  EXPECT_EQ(210  , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
+  EXPECT_EQ(211  , message.GetExtension(unittest::repeated_float_extension   , 0));
+  EXPECT_EQ(212  , message.GetExtension(unittest::repeated_double_extension  , 0));
+  EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension    , 0));
+  EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension  , 0));
+  EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension   , 0));
+
+  EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension           , 0).a());
+  EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
+  EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
+  EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
+  EXPECT_EQ(unittest::FOREIGN_BAR      , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
+  EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0));
+
+  EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0));
+  EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0));
+
+  EXPECT_EQ(301  , message.GetExtension(unittest::repeated_int32_extension   , 1));
+  EXPECT_EQ(302  , message.GetExtension(unittest::repeated_int64_extension   , 1));
+  EXPECT_EQ(303  , message.GetExtension(unittest::repeated_uint32_extension  , 1));
+  EXPECT_EQ(304  , message.GetExtension(unittest::repeated_uint64_extension  , 1));
+  EXPECT_EQ(305  , message.GetExtension(unittest::repeated_sint32_extension  , 1));
+  EXPECT_EQ(306  , message.GetExtension(unittest::repeated_sint64_extension  , 1));
+  EXPECT_EQ(307  , message.GetExtension(unittest::repeated_fixed32_extension , 1));
+  EXPECT_EQ(308  , message.GetExtension(unittest::repeated_fixed64_extension , 1));
+  EXPECT_EQ(309  , message.GetExtension(unittest::repeated_sfixed32_extension, 1));
+  EXPECT_EQ(310  , message.GetExtension(unittest::repeated_sfixed64_extension, 1));
+  EXPECT_EQ(311  , message.GetExtension(unittest::repeated_float_extension   , 1));
+  EXPECT_EQ(312  , message.GetExtension(unittest::repeated_double_extension  , 1));
+  EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension    , 1));
+  EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension  , 1));
+  EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension   , 1));
+
+  EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension           , 1).a());
+  EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb());
+  EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c());
+  EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 1).d());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 1));
+  EXPECT_EQ(unittest::FOREIGN_BAZ      , message.GetExtension(unittest::repeated_foreign_enum_extension, 1));
+  EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::repeated_import_enum_extension , 1));
+
+  EXPECT_EQ("324", message.GetExtension(unittest::repeated_string_piece_extension, 1));
+  EXPECT_EQ("325", message.GetExtension(unittest::repeated_cord_extension, 1));
+
+  // -----------------------------------------------------------------
+
+  EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension   ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension   ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::default_float_extension   ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_double_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension    ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_string_extension  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension   ));
+
+  EXPECT_TRUE(message.HasExtension(unittest::default_nested_enum_extension ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_foreign_enum_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::default_import_enum_extension ));
+
+  EXPECT_TRUE(message.HasExtension(unittest::default_string_piece_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::default_cord_extension));
+
+  EXPECT_EQ(401  , message.GetExtension(unittest::default_int32_extension   ));
+  EXPECT_EQ(402  , message.GetExtension(unittest::default_int64_extension   ));
+  EXPECT_EQ(403  , message.GetExtension(unittest::default_uint32_extension  ));
+  EXPECT_EQ(404  , message.GetExtension(unittest::default_uint64_extension  ));
+  EXPECT_EQ(405  , message.GetExtension(unittest::default_sint32_extension  ));
+  EXPECT_EQ(406  , message.GetExtension(unittest::default_sint64_extension  ));
+  EXPECT_EQ(407  , message.GetExtension(unittest::default_fixed32_extension ));
+  EXPECT_EQ(408  , message.GetExtension(unittest::default_fixed64_extension ));
+  EXPECT_EQ(409  , message.GetExtension(unittest::default_sfixed32_extension));
+  EXPECT_EQ(410  , message.GetExtension(unittest::default_sfixed64_extension));
+  EXPECT_EQ(411  , message.GetExtension(unittest::default_float_extension   ));
+  EXPECT_EQ(412  , message.GetExtension(unittest::default_double_extension  ));
+  EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension    ));
+  EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension  ));
+  EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension   ));
+
+  EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::default_nested_enum_extension ));
+  EXPECT_EQ(unittest::FOREIGN_FOO      , message.GetExtension(unittest::default_foreign_enum_extension));
+  EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::default_import_enum_extension ));
+
+  EXPECT_EQ("424", message.GetExtension(unittest::default_string_piece_extension));
+  EXPECT_EQ("425", message.GetExtension(unittest::default_cord_extension));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectExtensionsClear(
+    const unittest::TestAllExtensions& message) {
+  string serialized;
+  ASSERT_TRUE(message.SerializeToString(&serialized));
+  EXPECT_EQ("", serialized);
+  EXPECT_EQ(0, message.ByteSize());
+
+  // has_blah() should initially be false for all optional fields.
+  EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension   ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension   ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed32_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed64_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension   ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension    ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension   ));
+
+  EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension           ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension ));
+
+  EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_import_enum_extension ));
+
+  EXPECT_FALSE(message.HasExtension(unittest::optional_string_piece_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_cord_extension));
+
+  // Optional fields without defaults are set to zero or something like it.
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_int32_extension   ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_int64_extension   ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_uint32_extension  ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_uint64_extension  ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_sint32_extension  ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_sint64_extension  ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_fixed32_extension ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_fixed64_extension ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_sfixed32_extension));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_sfixed64_extension));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_float_extension   ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_double_extension  ));
+  EXPECT_EQ(false, message.GetExtension(unittest::optional_bool_extension    ));
+  EXPECT_EQ(""   , message.GetExtension(unittest::optional_string_extension  ));
+  EXPECT_EQ(""   , message.GetExtension(unittest::optional_bytes_extension   ));
+
+  // Embedded messages should also be clear.
+  EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension           ).has_a());
+  EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb());
+  EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension).has_c());
+  EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension ).has_d());
+
+  EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension           ).a());
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension ).bb());
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension).c());
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension ).d());
+
+  // Enums without defaults are set to the first value in the enum.
+  EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::optional_nested_enum_extension ));
+  EXPECT_EQ(unittest::FOREIGN_FOO      , message.GetExtension(unittest::optional_foreign_enum_extension));
+  EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::optional_import_enum_extension ));
+
+  EXPECT_EQ("", message.GetExtension(unittest::optional_string_piece_extension));
+  EXPECT_EQ("", message.GetExtension(unittest::optional_cord_extension));
+
+  // Repeated fields are empty.
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed32_extension ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed64_extension ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed32_extension));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed64_extension));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension    ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension   ));
+
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension           ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension    ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension    ));
+
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_piece_extension));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_cord_extension));
+
+  // has_blah() should also be false for all default fields.
+  EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension   ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension   ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::default_float_extension   ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_double_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension    ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_string_extension  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension   ));
+
+  EXPECT_FALSE(message.HasExtension(unittest::default_nested_enum_extension ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_foreign_enum_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::default_import_enum_extension ));
+
+  EXPECT_FALSE(message.HasExtension(unittest::default_string_piece_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::default_cord_extension));
+
+  // Fields with defaults have their default values (duh).
+  EXPECT_EQ( 41    , message.GetExtension(unittest::default_int32_extension   ));
+  EXPECT_EQ( 42    , message.GetExtension(unittest::default_int64_extension   ));
+  EXPECT_EQ( 43    , message.GetExtension(unittest::default_uint32_extension  ));
+  EXPECT_EQ( 44    , message.GetExtension(unittest::default_uint64_extension  ));
+  EXPECT_EQ(-45    , message.GetExtension(unittest::default_sint32_extension  ));
+  EXPECT_EQ( 46    , message.GetExtension(unittest::default_sint64_extension  ));
+  EXPECT_EQ( 47    , message.GetExtension(unittest::default_fixed32_extension ));
+  EXPECT_EQ( 48    , message.GetExtension(unittest::default_fixed64_extension ));
+  EXPECT_EQ( 49    , message.GetExtension(unittest::default_sfixed32_extension));
+  EXPECT_EQ(-50    , message.GetExtension(unittest::default_sfixed64_extension));
+  EXPECT_EQ( 51.5  , message.GetExtension(unittest::default_float_extension   ));
+  EXPECT_EQ( 52e3  , message.GetExtension(unittest::default_double_extension  ));
+  EXPECT_EQ(true   , message.GetExtension(unittest::default_bool_extension    ));
+  EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension  ));
+  EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension   ));
+
+  EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::default_nested_enum_extension ));
+  EXPECT_EQ(unittest::FOREIGN_BAR      , message.GetExtension(unittest::default_foreign_enum_extension));
+  EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::default_import_enum_extension ));
+
+  EXPECT_EQ("abc", message.GetExtension(unittest::default_string_piece_extension));
+  EXPECT_EQ("123", message.GetExtension(unittest::default_cord_extension));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectRepeatedExtensionsModified(
+    const unittest::TestAllExtensions& message) {
+  // ModifyRepeatedFields only sets the second repeated element of each
+  // field.  In addition to verifying this, we also verify that the first
+  // element and size were *not* modified.
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension   ));
+
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension           ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension    ));
+
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension));
+
+  EXPECT_EQ(201  , message.GetExtension(unittest::repeated_int32_extension   , 0));
+  EXPECT_EQ(202  , message.GetExtension(unittest::repeated_int64_extension   , 0));
+  EXPECT_EQ(203  , message.GetExtension(unittest::repeated_uint32_extension  , 0));
+  EXPECT_EQ(204  , message.GetExtension(unittest::repeated_uint64_extension  , 0));
+  EXPECT_EQ(205  , message.GetExtension(unittest::repeated_sint32_extension  , 0));
+  EXPECT_EQ(206  , message.GetExtension(unittest::repeated_sint64_extension  , 0));
+  EXPECT_EQ(207  , message.GetExtension(unittest::repeated_fixed32_extension , 0));
+  EXPECT_EQ(208  , message.GetExtension(unittest::repeated_fixed64_extension , 0));
+  EXPECT_EQ(209  , message.GetExtension(unittest::repeated_sfixed32_extension, 0));
+  EXPECT_EQ(210  , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
+  EXPECT_EQ(211  , message.GetExtension(unittest::repeated_float_extension   , 0));
+  EXPECT_EQ(212  , message.GetExtension(unittest::repeated_double_extension  , 0));
+  EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension    , 0));
+  EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension  , 0));
+  EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension   , 0));
+
+  EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension           , 0).a());
+  EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
+  EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
+  EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
+  EXPECT_EQ(unittest::FOREIGN_BAR      , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
+  EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0));
+
+  EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0));
+  EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0));
+
+  // Actually verify the second (modified) elements now.
+  EXPECT_EQ(501  , message.GetExtension(unittest::repeated_int32_extension   , 1));
+  EXPECT_EQ(502  , message.GetExtension(unittest::repeated_int64_extension   , 1));
+  EXPECT_EQ(503  , message.GetExtension(unittest::repeated_uint32_extension  , 1));
+  EXPECT_EQ(504  , message.GetExtension(unittest::repeated_uint64_extension  , 1));
+  EXPECT_EQ(505  , message.GetExtension(unittest::repeated_sint32_extension  , 1));
+  EXPECT_EQ(506  , message.GetExtension(unittest::repeated_sint64_extension  , 1));
+  EXPECT_EQ(507  , message.GetExtension(unittest::repeated_fixed32_extension , 1));
+  EXPECT_EQ(508  , message.GetExtension(unittest::repeated_fixed64_extension , 1));
+  EXPECT_EQ(509  , message.GetExtension(unittest::repeated_sfixed32_extension, 1));
+  EXPECT_EQ(510  , message.GetExtension(unittest::repeated_sfixed64_extension, 1));
+  EXPECT_EQ(511  , message.GetExtension(unittest::repeated_float_extension   , 1));
+  EXPECT_EQ(512  , message.GetExtension(unittest::repeated_double_extension  , 1));
+  EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension    , 1));
+  EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension  , 1));
+  EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension   , 1));
+
+  EXPECT_EQ(517, message.GetExtension(unittest::repeatedgroup_extension           , 1).a());
+  EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb());
+  EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c());
+  EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension , 1).d());
+
+  EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::repeated_nested_enum_extension , 1));
+  EXPECT_EQ(unittest::FOREIGN_FOO      , message.GetExtension(unittest::repeated_foreign_enum_extension, 1));
+  EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::repeated_import_enum_extension , 1));
+
+  EXPECT_EQ("524", message.GetExtension(unittest::repeated_string_piece_extension, 1));
+  EXPECT_EQ("525", message.GetExtension(unittest::repeated_cord_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectAllFieldsAndExtensionsInOrder(const string& serialized) {
+  // We set each field individually, serialize separately, and concatenate all
+  // the strings in canonical order to determine the expected serialization.
+  string expected;
+  unittest::TestFieldOrderings message;
+  message.set_my_int(1);  // Field 1.
+  message.AppendToString(&expected);
+  message.Clear();
+  message.SetExtension(unittest::my_extension_int, 23);  // Field 5.
+  message.AppendToString(&expected);
+  message.Clear();
+  message.set_my_string("foo");  // Field 11.
+  message.AppendToString(&expected);
+  message.Clear();
+  message.SetExtension(unittest::my_extension_string, "bar");  // Field 50.
+  message.AppendToString(&expected);
+  message.Clear();
+  message.set_my_float(1.0);  // Field 101.
+  message.AppendToString(&expected);
+  message.Clear();
+
+  // We don't EXPECT_EQ() since we don't want to print raw bytes to stdout.
+  EXPECT_TRUE(serialized == expected);
+}
+
+// ===================================================================
+
+TestUtil::ReflectionTester::ReflectionTester(
+    const Descriptor* base_descriptor)
+  : base_descriptor_(base_descriptor) {
+
+  const DescriptorPool* pool = base_descriptor->file()->pool();
+
+  nested_b_ =
+    pool->FindFieldByName("protobuf_unittest.TestAllTypes.NestedMessage.bb");
+  foreign_c_ =
+    pool->FindFieldByName("protobuf_unittest.ForeignMessage.c");
+  import_d_ =
+    pool->FindFieldByName("protobuf_unittest_import.ImportMessage.d");
+  nested_foo_ =
+    pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.FOO");
+  nested_bar_ =
+    pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.BAR");
+  nested_baz_ =
+    pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.BAZ");
+  foreign_foo_ =
+    pool->FindEnumValueByName("protobuf_unittest.FOREIGN_FOO");
+  foreign_bar_ =
+    pool->FindEnumValueByName("protobuf_unittest.FOREIGN_BAR");
+  foreign_baz_ =
+    pool->FindEnumValueByName("protobuf_unittest.FOREIGN_BAZ");
+  import_foo_ =
+    pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_FOO");
+  import_bar_ =
+    pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_BAR");
+  import_baz_ =
+    pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_BAZ");
+
+  if (base_descriptor_->name() == "TestAllExtensions") {
+    group_a_ =
+      pool->FindFieldByName("protobuf_unittest.OptionalGroup_extension.a");
+    repeated_group_a_ =
+      pool->FindFieldByName("protobuf_unittest.RepeatedGroup_extension.a");
+  } else {
+    group_a_ =
+      pool->FindFieldByName("protobuf_unittest.TestAllTypes.OptionalGroup.a");
+    repeated_group_a_ =
+      pool->FindFieldByName("protobuf_unittest.TestAllTypes.RepeatedGroup.a");
+  }
+
+  EXPECT_TRUE(group_a_          != NULL);
+  EXPECT_TRUE(repeated_group_a_ != NULL);
+  EXPECT_TRUE(nested_b_         != NULL);
+  EXPECT_TRUE(foreign_c_        != NULL);
+  EXPECT_TRUE(import_d_         != NULL);
+  EXPECT_TRUE(nested_foo_       != NULL);
+  EXPECT_TRUE(nested_bar_       != NULL);
+  EXPECT_TRUE(nested_baz_       != NULL);
+  EXPECT_TRUE(foreign_foo_      != NULL);
+  EXPECT_TRUE(foreign_bar_      != NULL);
+  EXPECT_TRUE(foreign_baz_      != NULL);
+  EXPECT_TRUE(import_foo_       != NULL);
+  EXPECT_TRUE(import_bar_       != NULL);
+  EXPECT_TRUE(import_baz_       != NULL);
+}
+
+// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
+const FieldDescriptor* TestUtil::ReflectionTester::F(const string& name) {
+  const FieldDescriptor* result = NULL;
+  if (base_descriptor_->name() == "TestAllExtensions") {
+    result = base_descriptor_->file()->FindExtensionByName(name + "_extension");
+  } else {
+    result = base_descriptor_->FindFieldByName(name);
+  }
+  GOOGLE_CHECK(result != NULL);
+  return result;
+}
+
+// -------------------------------------------------------------------
+
+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");
+
+  // -----------------------------------------------------------------
+
+  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");
+
+  // 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");
+
+  // -----------------------------------------------------------------
+
+  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");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection(
+    const Message::Reflection& message) {
+  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));
+
+  // -----------------------------------------------------------------
+
+  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));
+
+  // -----------------------------------------------------------------
+
+  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));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ReflectionTester::ExpectClearViaReflection(
+    const Message::Reflection& message) {
+  string scratch;
+
+  // 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")));
+
+  // 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));
+
+  // 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_));
+
+  // 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("", message.GetString(F("optional_string_piece")));
+  EXPECT_EQ("", message.GetStringReference(F("optional_string_piece"),
+                                           &scratch));
+
+  EXPECT_EQ("", message.GetString(F("optional_cord")));
+  EXPECT_EQ("", message.GetStringReference(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")));
+
+  // 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")));
+
+  // 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));
+}
+
+// -------------------------------------------------------------------
+
+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");
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/test_util.h b/src/google/protobuf/test_util.h
new file mode 100644
index 0000000..4157d09
--- /dev/null
+++ b/src/google/protobuf/test_util.h
@@ -0,0 +1,118 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_TEST_UTIL_H__
+#define GOOGLE_PROTOBUF_TEST_UTIL_H__
+
+#include <stack>
+#include <string>
+#include <google/protobuf/message.h>
+#include <google/protobuf/unittest.pb.h>
+
+namespace google {
+namespace protobuf {
+
+namespace unittest = protobuf_unittest;
+namespace unittest_import = protobuf_unittest_import;
+
+class TestUtil {
+ public:
+  // Set every field in the message to a unique value.
+  static void SetAllFields(unittest::TestAllTypes* message);
+  static void SetAllExtensions(unittest::TestAllExtensions* message);
+  static void SetAllFieldsAndExtensions(unittest::TestFieldOrderings* message);
+
+  // Use the repeated versions of the set_*() accessors to modify all the
+  // repeated fields of the messsage (which should already have been
+  // initialized with SetAllFields()).  SetAllFields() itself only tests
+  // the add_*() accessors.
+  static void ModifyRepeatedFields(unittest::TestAllTypes* message);
+  static void ModifyRepeatedExtensions(unittest::TestAllExtensions* message);
+
+  // Check that all fields have the values that they should have after
+  // SetAllFields() is called.
+  static void ExpectAllFieldsSet(const unittest::TestAllTypes& message);
+  static void ExpectAllExtensionsSet(
+      const unittest::TestAllExtensions& message);
+
+  // Expect that the message is modified as would be expected from
+  // ModifyRepeatedFields().
+  static void ExpectRepeatedFieldsModified(
+      const unittest::TestAllTypes& message);
+  static void ExpectRepeatedExtensionsModified(
+      const unittest::TestAllExtensions& message);
+
+  // Check that all fields have their default values.
+  static void ExpectClear(const unittest::TestAllTypes& message);
+  static void ExpectExtensionsClear(const unittest::TestAllExtensions& message);
+
+  // Check that the passed-in serialization is the canonical serialization we
+  // expect for a TestFieldOrderings message filled in by
+  // SetAllFieldsAndExtensions().
+  static void ExpectAllFieldsAndExtensionsInOrder(const string& serialized);
+
+  // Like above, but use the reflection interface.
+  class ReflectionTester {
+   public:
+    // base_descriptor must be a descriptor for TestAllTypes or
+    // TestAllExtensions.  In the former case, ReflectionTester fetches from
+    // it the FieldDescriptors needed to use the reflection interface.  In
+    // the latter case, ReflectionTester searches for extension fields in
+    // 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);
+
+   private:
+    const FieldDescriptor* F(const string& name);
+
+    const Descriptor* base_descriptor_;
+
+    const FieldDescriptor* group_a_;
+    const FieldDescriptor* repeated_group_a_;
+    const FieldDescriptor* nested_b_;
+    const FieldDescriptor* foreign_c_;
+    const FieldDescriptor* import_d_;
+
+    const EnumValueDescriptor* nested_foo_;
+    const EnumValueDescriptor* nested_bar_;
+    const EnumValueDescriptor* nested_baz_;
+    const EnumValueDescriptor* foreign_foo_;
+    const EnumValueDescriptor* foreign_bar_;
+    const EnumValueDescriptor* foreign_baz_;
+    const EnumValueDescriptor* import_foo_;
+    const EnumValueDescriptor* import_bar_;
+    const EnumValueDescriptor* import_baz_;
+
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionTester);
+  };
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtil);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_TEST_UTIL_H__
diff --git a/src/google/protobuf/testdata/golden_message b/src/google/protobuf/testdata/golden_message
new file mode 100644
index 0000000..94898e4
--- /dev/null
+++ b/src/google/protobuf/testdata/golden_message
Binary files differ
diff --git a/src/google/protobuf/testdata/text_format_unittest_data.txt b/src/google/protobuf/testdata/text_format_unittest_data.txt
new file mode 100644
index 0000000..feea8f7
--- /dev/null
+++ b/src/google/protobuf/testdata/text_format_unittest_data.txt
@@ -0,0 +1,116 @@
+optional_int32: 101
+optional_int64: 102
+optional_uint32: 103
+optional_uint64: 104
+optional_sint32: 105
+optional_sint64: 106
+optional_fixed32: 107
+optional_fixed64: 108
+optional_sfixed32: 109
+optional_sfixed64: 110
+optional_float: 111
+optional_double: 112
+optional_bool: true
+optional_string: "115"
+optional_bytes: "116"
+OptionalGroup {
+  a: 117
+}
+optional_nested_message {
+  bb: 118
+}
+optional_foreign_message {
+  c: 119
+}
+optional_import_message {
+  d: 120
+}
+optional_nested_enum: BAZ
+optional_foreign_enum: FOREIGN_BAZ
+optional_import_enum: IMPORT_BAZ
+optional_string_piece: "124"
+optional_cord: "125"
+repeated_int32: 201
+repeated_int32: 301
+repeated_int64: 202
+repeated_int64: 302
+repeated_uint32: 203
+repeated_uint32: 303
+repeated_uint64: 204
+repeated_uint64: 304
+repeated_sint32: 205
+repeated_sint32: 305
+repeated_sint64: 206
+repeated_sint64: 306
+repeated_fixed32: 207
+repeated_fixed32: 307
+repeated_fixed64: 208
+repeated_fixed64: 308
+repeated_sfixed32: 209
+repeated_sfixed32: 309
+repeated_sfixed64: 210
+repeated_sfixed64: 310
+repeated_float: 211
+repeated_float: 311
+repeated_double: 212
+repeated_double: 312
+repeated_bool: true
+repeated_bool: false
+repeated_string: "215"
+repeated_string: "315"
+repeated_bytes: "216"
+repeated_bytes: "316"
+RepeatedGroup {
+  a: 217
+}
+RepeatedGroup {
+  a: 317
+}
+repeated_nested_message {
+  bb: 218
+}
+repeated_nested_message {
+  bb: 318
+}
+repeated_foreign_message {
+  c: 219
+}
+repeated_foreign_message {
+  c: 319
+}
+repeated_import_message {
+  d: 220
+}
+repeated_import_message {
+  d: 320
+}
+repeated_nested_enum: BAR
+repeated_nested_enum: BAZ
+repeated_foreign_enum: FOREIGN_BAR
+repeated_foreign_enum: FOREIGN_BAZ
+repeated_import_enum: IMPORT_BAR
+repeated_import_enum: IMPORT_BAZ
+repeated_string_piece: "224"
+repeated_string_piece: "324"
+repeated_cord: "225"
+repeated_cord: "325"
+default_int32: 401
+default_int64: 402
+default_uint32: 403
+default_uint64: 404
+default_sint32: 405
+default_sint64: 406
+default_fixed32: 407
+default_fixed64: 408
+default_sfixed32: 409
+default_sfixed64: 410
+default_float: 411
+default_double: 412
+default_bool: false
+default_string: "415"
+default_bytes: "416"
+default_nested_enum: FOO
+default_foreign_enum: FOREIGN_FOO
+default_import_enum: IMPORT_FOO
+default_string_piece: "424"
+default_cord: "425"
diff --git a/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt b/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt
new file mode 100644
index 0000000..057beae
--- /dev/null
+++ b/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt
@@ -0,0 +1,116 @@
+[protobuf_unittest.optional_int32_extension]: 101
+[protobuf_unittest.optional_int64_extension]: 102
+[protobuf_unittest.optional_uint32_extension]: 103
+[protobuf_unittest.optional_uint64_extension]: 104
+[protobuf_unittest.optional_sint32_extension]: 105
+[protobuf_unittest.optional_sint64_extension]: 106
+[protobuf_unittest.optional_fixed32_extension]: 107
+[protobuf_unittest.optional_fixed64_extension]: 108
+[protobuf_unittest.optional_sfixed32_extension]: 109
+[protobuf_unittest.optional_sfixed64_extension]: 110
+[protobuf_unittest.optional_float_extension]: 111
+[protobuf_unittest.optional_double_extension]: 112
+[protobuf_unittest.optional_bool_extension]: true
+[protobuf_unittest.optional_string_extension]: "115"
+[protobuf_unittest.optional_bytes_extension]: "116"
+[protobuf_unittest.optionalgroup_extension] {
+  a: 117
+}
+[protobuf_unittest.optional_nested_message_extension] {
+  bb: 118
+}
+[protobuf_unittest.optional_foreign_message_extension] {
+  c: 119
+}
+[protobuf_unittest.optional_import_message_extension] {
+  d: 120
+}
+[protobuf_unittest.optional_nested_enum_extension]: BAZ
+[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.optional_string_piece_extension]: "124"
+[protobuf_unittest.optional_cord_extension]: "125"
+[protobuf_unittest.repeated_int32_extension]: 201
+[protobuf_unittest.repeated_int32_extension]: 301
+[protobuf_unittest.repeated_int64_extension]: 202
+[protobuf_unittest.repeated_int64_extension]: 302
+[protobuf_unittest.repeated_uint32_extension]: 203
+[protobuf_unittest.repeated_uint32_extension]: 303
+[protobuf_unittest.repeated_uint64_extension]: 204
+[protobuf_unittest.repeated_uint64_extension]: 304
+[protobuf_unittest.repeated_sint32_extension]: 205
+[protobuf_unittest.repeated_sint32_extension]: 305
+[protobuf_unittest.repeated_sint64_extension]: 206
+[protobuf_unittest.repeated_sint64_extension]: 306
+[protobuf_unittest.repeated_fixed32_extension]: 207
+[protobuf_unittest.repeated_fixed32_extension]: 307
+[protobuf_unittest.repeated_fixed64_extension]: 208
+[protobuf_unittest.repeated_fixed64_extension]: 308
+[protobuf_unittest.repeated_sfixed32_extension]: 209
+[protobuf_unittest.repeated_sfixed32_extension]: 309
+[protobuf_unittest.repeated_sfixed64_extension]: 210
+[protobuf_unittest.repeated_sfixed64_extension]: 310
+[protobuf_unittest.repeated_float_extension]: 211
+[protobuf_unittest.repeated_float_extension]: 311
+[protobuf_unittest.repeated_double_extension]: 212
+[protobuf_unittest.repeated_double_extension]: 312
+[protobuf_unittest.repeated_bool_extension]: true
+[protobuf_unittest.repeated_bool_extension]: false
+[protobuf_unittest.repeated_string_extension]: "215"
+[protobuf_unittest.repeated_string_extension]: "315"
+[protobuf_unittest.repeated_bytes_extension]: "216"
+[protobuf_unittest.repeated_bytes_extension]: "316"
+[protobuf_unittest.repeatedgroup_extension] {
+  a: 217
+}
+[protobuf_unittest.repeatedgroup_extension] {
+  a: 317
+}
+[protobuf_unittest.repeated_nested_message_extension] {
+  bb: 218
+}
+[protobuf_unittest.repeated_nested_message_extension] {
+  bb: 318
+}
+[protobuf_unittest.repeated_foreign_message_extension] {
+  c: 219
+}
+[protobuf_unittest.repeated_foreign_message_extension] {
+  c: 319
+}
+[protobuf_unittest.repeated_import_message_extension] {
+  d: 220
+}
+[protobuf_unittest.repeated_import_message_extension] {
+  d: 320
+}
+[protobuf_unittest.repeated_nested_enum_extension]: BAR
+[protobuf_unittest.repeated_nested_enum_extension]: BAZ
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.repeated_string_piece_extension]: "224"
+[protobuf_unittest.repeated_string_piece_extension]: "324"
+[protobuf_unittest.repeated_cord_extension]: "225"
+[protobuf_unittest.repeated_cord_extension]: "325"
+[protobuf_unittest.default_int32_extension]: 401
+[protobuf_unittest.default_int64_extension]: 402
+[protobuf_unittest.default_uint32_extension]: 403
+[protobuf_unittest.default_uint64_extension]: 404
+[protobuf_unittest.default_sint32_extension]: 405
+[protobuf_unittest.default_sint64_extension]: 406
+[protobuf_unittest.default_fixed32_extension]: 407
+[protobuf_unittest.default_fixed64_extension]: 408
+[protobuf_unittest.default_sfixed32_extension]: 409
+[protobuf_unittest.default_sfixed64_extension]: 410
+[protobuf_unittest.default_float_extension]: 411
+[protobuf_unittest.default_double_extension]: 412
+[protobuf_unittest.default_bool_extension]: false
+[protobuf_unittest.default_string_extension]: "415"
+[protobuf_unittest.default_bytes_extension]: "416"
+[protobuf_unittest.default_nested_enum_extension]: FOO
+[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO
+[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO
+[protobuf_unittest.default_string_piece_extension]: "424"
+[protobuf_unittest.default_cord_extension]: "425"
diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc
new file mode 100644
index 0000000..473d691
--- /dev/null
+++ b/src/google/protobuf/testing/file.cc
@@ -0,0 +1,157 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+// emulates google3/file/base/file.cc
+
+#include <google/protobuf/testing/file.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#ifdef _MSC_VER
+#define WIN32_LEAN_AND_MEAN  // yeah, right
+#include <windows.h>         // Find*File().  :(
+#include <io.h>
+#include <direct.h>
+#else
+#include <dirent.h>
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _WIN32
+#define mkdir(name, mode) mkdir(name)
+// Windows doesn't have symbolic links.
+#define lstat stat
+#ifndef F_OK
+#define F_OK 00  // not defined by MSVC for whatever reason
+#endif
+#endif
+
+bool File::Exists(const string& name) {
+  return access(name.c_str(), F_OK) == 0;
+}
+
+bool File::ReadFileToString(const string& name, string* output) {
+  char buffer[1024];
+  FILE* file = fopen(name.c_str(), "rb");
+  if (file == NULL) return false;
+
+  while (true) {
+    size_t n = fread(buffer, 1, sizeof(buffer), file);
+    if (n <= 0) break;
+    output->append(buffer, n);
+  }
+
+  int error = ferror(file);
+  if (fclose(file) != 0) return false;
+  return error == 0;
+}
+
+void File::ReadFileToStringOrDie(const string& name, string* output) {
+  GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name;
+}
+
+void File::WriteStringToFileOrDie(const string& contents, const string& name) {
+  FILE* file = fopen(name.c_str(), "wb");
+  GOOGLE_CHECK(file != NULL);
+  GOOGLE_CHECK_EQ(fwrite(contents.data(), 1, contents.size(), file),
+                  contents.size());
+  GOOGLE_CHECK(fclose(file) == 0);
+}
+
+bool File::CreateDir(const string& name, int mode) {
+  return mkdir(name.c_str(), mode) == 0;
+}
+
+bool File::RecursivelyCreateDir(const string& path, int mode) {
+  if (CreateDir(path, mode)) return true;
+
+  // Try creating the parent.
+  string::size_type slashpos = path.find_first_of('/');
+  if (slashpos == string::npos) {
+    // No parent given.
+    return false;
+  }
+
+  return RecursivelyCreateDir(path.substr(0, slashpos), mode) &&
+         CreateDir(path, mode);
+}
+
+void File::DeleteRecursively(const string& name,
+                             void* dummy1, void* dummy2) {
+  // We don't care too much about error checking here since this is only used
+  // in tests to delete temporary directories that are under /tmp anyway.
+
+#ifdef _MSC_VER
+  // This interface is so weird.
+  WIN32_FIND_DATA find_data;
+  HANDLE find_handle = FindFirstFile((name + "/*").c_str(), &find_data);
+  if (find_handle == INVALID_HANDLE_VALUE) {
+    // Just delete it, whatever it is.
+    DeleteFile(name.c_str());
+    RemoveDirectory(name.c_str());
+    return;
+  }
+
+  do {
+    string entry_name = find_data.cFileName;
+    if (entry_name != "." && entry_name != "..") {
+      string path = name + "/" + entry_name;
+      if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        DeleteRecursively(path, NULL, NULL);
+        RemoveDirectory(path.c_str());
+      } else {
+        DeleteFile(path.c_str());
+      }
+    }
+  } while(FindNextFile(find_handle, &find_data));
+  FindClose(find_handle);
+
+  RemoveDirectory(name.c_str());
+#else
+  // Use opendir()!  Yay!
+  // lstat = Don't follow symbolic links.
+  struct stat stats;
+  if (lstat(name.c_str(), &stats) != 0) return;
+
+  if (S_ISDIR(stats.st_mode)) {
+    DIR* dir = opendir(name.c_str());
+    if (dir != NULL) {
+      while (true) {
+        struct dirent* entry = readdir(dir);
+        if (entry == NULL) break;
+        string entry_name = entry->d_name;
+        if (entry_name != "." && entry_name != "..") {
+          DeleteRecursively(name + "/" + entry_name, NULL, NULL);
+        }
+      }
+    }
+
+    closedir(dir);
+    rmdir(name.c_str());
+
+  } else if (S_ISREG(stats.st_mode)) {
+    remove(name.c_str());
+  }
+#endif
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/testing/file.h b/src/google/protobuf/testing/file.h
new file mode 100644
index 0000000..93335f1
--- /dev/null
+++ b/src/google/protobuf/testing/file.h
@@ -0,0 +1,69 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+// emulates google3/file/base/file.h
+
+#ifndef GOOGLE_PROTOBUF_TESTING_FILE_H__
+#define GOOGLE_PROTOBUF_TESTING_FILE_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+const int DEFAULT_FILE_MODE = 0777;
+
+// Protocol buffer code only uses a couple static methods of File, and only
+// in tests.
+class File {
+ public:
+  // Check if the file exists.
+  static bool Exists(const string& name);
+
+  // Read an entire file to a string.  Return true if successful, false
+  // otherwise.
+  static bool ReadFileToString(const string& name, string* output);
+
+  // Same as above, but crash on failure.
+  static void ReadFileToStringOrDie(const string& name, string* output);
+
+  // Create a file and write a string to it.
+  static void WriteStringToFileOrDie(const string& contents,
+                                     const string& name);
+
+  // Create a directory.
+  static bool CreateDir(const string& name, int mode);
+
+  // Create a directory and all parent directories if necessary.
+  static bool RecursivelyCreateDir(const string& path, int mode);
+
+  // If "name" is a file, we delete it.  If it is a directory, we
+  // call DeleteRecursively() for each file or directory (other than
+  // dot and double-dot) within it, and then delete the directory itself.
+  // The "dummy" parameters have a meaning in the original version of this
+  // method but they are not used anywhere in protocol buffers.
+  static void DeleteRecursively(const string& name,
+                                void* dummy1, void* dummy2);
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(File);
+};
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_TESTING_FILE_H__
diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc
new file mode 100644
index 0000000..aabc657
--- /dev/null
+++ b/src/google/protobuf/testing/googletest.cc
@@ -0,0 +1,189 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+// emulates google3/testing/base/public/googletest.cc
+
+#include <google/protobuf/testing/googletest.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+#include <io.h>
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <fcntl.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _WIN32
+#define mkdir(name, mode) mkdir(name)
+#endif
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0     // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+string TestSourceDir() {
+#ifdef _MSC_VER
+  // Look for the "src" directory.
+  string prefix = ".";
+
+  while (!File::Exists(prefix + "/src/google/protobuf")) {
+    if (!File::Exists(prefix)) {
+      GOOGLE_LOG(FATAL)
+        << "Could not find protobuf source code.  Please run tests from "
+           "somewhere within the protobuf source package.";
+    }
+    prefix += "/..";
+  }
+  return prefix + "/src";
+#else
+  // automake sets the "srcdir" environment variable.
+  char* result = getenv("srcdir");
+  if (result == NULL) {
+    // Otherwise, the test must be run from the source directory.
+    return ".";
+  } else {
+    return result;
+  }
+#endif
+}
+
+namespace {
+
+string GetTemporaryDirectoryName() {
+  // tmpnam() is generally not considered safe but we're only using it for
+  // testing.  We cannot use tmpfile() or mkstemp() since we're creating a
+  // directory.
+  string result = tmpnam(NULL);
+#ifdef _WIN32
+  // On Win32, tmpnam() returns a file prefixed with '\', but which is supposed
+  // to be used in the current working directory.  WTF?
+  if (HasPrefixString(result, "\\")) {
+    result.erase(0, 1);
+  }
+#endif  // _WIN32
+  return result;
+}
+
+// Creates a temporary directory on demand and deletes it when the process
+// quits.
+class TempDirDeleter {
+ public:
+  TempDirDeleter() {}
+  ~TempDirDeleter() {
+    if (!name_.empty()) {
+      File::DeleteRecursively(name_, NULL, NULL);
+    }
+  }
+
+  string GetTempDir() {
+    if (name_.empty()) {
+      name_ = GetTemporaryDirectoryName();
+      GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno);
+
+      // Stick a file in the directory that tells people what this is, in case
+      // we abort and don't get a chance to delete it.
+      File::WriteStringToFileOrDie("", name_ + "/TEMP_DIR_FOR_PROTOBUF_TESTS");
+    }
+    return name_;
+  }
+
+ private:
+  string name_;
+};
+
+TempDirDeleter temp_dir_deleter_;
+
+}  // namespace
+
+string TestTempDir() {
+  return temp_dir_deleter_.GetTempDir();
+}
+
+static string stderr_capture_filename_;
+static int original_stderr_ = -1;
+
+void CaptureTestStderr() {
+  GOOGLE_CHECK_EQ(original_stderr_, -1) << "Already capturing.";
+
+  stderr_capture_filename_ = TestTempDir() + "/captured_stderr";
+
+  int fd = open(stderr_capture_filename_.c_str(),
+                O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777);
+  GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno);
+
+  original_stderr_ = dup(2);
+  close(2);
+  dup2(fd, 2);
+  close(fd);
+}
+
+string GetCapturedTestStderr() {
+  GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing.";
+
+  close(2);
+  dup2(original_stderr_, 2);
+  original_stderr_ = -1;
+
+  string result;
+  File::ReadFileToStringOrDie(stderr_capture_filename_, &result);
+
+  remove(stderr_capture_filename_.c_str());
+
+  return result;
+}
+
+ScopedMemoryLog* ScopedMemoryLog::active_log_ = NULL;
+
+ScopedMemoryLog::ScopedMemoryLog() {
+  GOOGLE_CHECK(active_log_ == NULL);
+  active_log_ = this;
+  old_handler_ = SetLogHandler(&HandleLog);
+}
+
+ScopedMemoryLog::~ScopedMemoryLog() {
+  SetLogHandler(old_handler_);
+  active_log_ = NULL;
+}
+
+const vector<string>& ScopedMemoryLog::GetMessages(LogLevel dummy) const {
+  GOOGLE_CHECK_EQ(dummy, ERROR);
+  return messages_;
+}
+
+void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename,
+                                int line, const string& message) {
+  GOOGLE_CHECK(active_log_ != NULL);
+  if (level == ERROR) {
+    active_log_->messages_.push_back(message);
+  }
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/testing/googletest.h b/src/google/protobuf/testing/googletest.h
new file mode 100644
index 0000000..9420641
--- /dev/null
+++ b/src/google/protobuf/testing/googletest.h
@@ -0,0 +1,81 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+// emulates google3/testing/base/public/googletest.h
+
+#ifndef GOOGLE_PROTOBUF_GOOGLETEST_H__
+#define GOOGLE_PROTOBUF_GOOGLETEST_H__
+
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// When running unittests, get the directory containing the source code.
+string TestSourceDir();
+
+// When running unittests, get a directory where temporary files may be
+// placed.
+string TestTempDir();
+
+// Capture all text written to stderr.
+void CaptureTestStderr();
+
+// Stop capturing stderr and return the text captured.
+string GetCapturedTestStderr();
+
+// For use with ScopedMemoryLog::GetMessages().  Inside Google the LogLevel
+// constants don't have the LOGLEVEL_ prefix, so the code that used
+// ScopedMemoryLog refers to LOGLEVEL_ERROR as just ERROR.
+static const LogLevel ERROR = LOGLEVEL_ERROR;
+
+// Receives copies of all LOG(ERROR) messages while in scope.  Sample usage:
+//   {
+//     ScopedMemoryLog log;  // constructor registers object as a log sink
+//     SomeRoutineThatMayLogMessages();
+//     const vector<string>& warnings = log.GetMessages(ERROR);
+//   }  // destructor unregisters object as a log sink
+// This is a dummy implementation which covers only what is used by protocol
+// buffer unit tests.
+class ScopedMemoryLog {
+ public:
+  ScopedMemoryLog();
+  virtual ~ScopedMemoryLog();
+
+  // Fetches all messages logged.  The internal version of this class
+  // would only fetch messages at the given security level, but the protobuf
+  // open source version ignores the argument since we always pass ERROR
+  // anyway.
+  const vector<string>& GetMessages(LogLevel dummy) const;
+
+ private:
+  vector<string> messages_;
+  LogHandler* old_handler_;
+
+  static void HandleLog(LogLevel level, const char* filename, int line,
+                        const string& message);
+
+  static ScopedMemoryLog* active_log_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedMemoryLog);
+};
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_GOOGLETEST_H__
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
new file mode 100644
index 0000000..63a64db
--- /dev/null
+++ b/src/google/protobuf/text_format.cc
@@ -0,0 +1,941 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: jschorr@google.com (Joseph Schorr)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <float.h>
+#include <math.h>
+#include <stack>
+#include <limits>
+
+#include <google/protobuf/text_format.h>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+
+string Message::DebugString() const {
+  string debug_string;
+  io::StringOutputStream output_stream(&debug_string);
+
+  TextFormat::Print(*this, &output_stream);
+
+  return debug_string;
+}
+
+string Message::ShortDebugString() const {
+  // TODO(kenton):  Make TextFormat support this natively instead of using
+  //   DebugString() and munging the result.
+  string result = DebugString();
+
+  // Replace each contiguous range of whitespace (including newlines) with a
+  // single space.
+  for (int i = 0; i < result.size(); i++) {
+    int pos = i;
+    while (isspace(result[pos])) ++pos;
+    if (pos > i) result.replace(i, pos - i, " ");
+  }
+
+  return result;
+}
+
+void Message::PrintDebugString() const {
+  printf("%s", DebugString().c_str());
+}
+
+// ===========================================================================
+// Internal class for parsing an ASCII representation of a Protocol Message.
+// This class makes use of the Protocol Message compiler's tokenizer found
+// in //google/protobuf/io/tokenizer.h. Note that class's Parse
+// method is *not* thread-safe and should only be used in a single thread at
+// a time.
+
+// Makes code slightly more readable.  The meaning of "DO(foo)" is
+// "Execute foo and fail if it fails.", where failure is indicated by
+// returning false. Borrowed from parser.cc (Thanks Kenton!).
+#define DO(STATEMENT) if (STATEMENT) {} else return false
+
+class TextFormat::ParserImpl {
+ public:
+  ParserImpl(io::ZeroCopyInputStream* input_stream,
+             io::ErrorCollector* error_collector)
+    : error_collector_(error_collector),
+      tokenizer_error_collector_(this),
+      tokenizer_(input_stream, &tokenizer_error_collector_),
+      root_message_type_(NULL) {
+    // For backwards-compatibility with proto1, we need to allow the 'f' suffix
+    // for floats.
+    tokenizer_.set_allow_f_after_float(true);
+
+    // '#' starts a comment.
+    tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
+
+    // Consume the starting token.
+    tokenizer_.Next();
+  }
+  ~ParserImpl() { }
+
+  // Parses the ASCII representation specified in input and saves the
+  // information into the output pointer (a Message). Returns
+  // 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;
+
+    // Consume fields until we cannot do so anymore.
+    while(true) {
+      if (LookingAtType(io::Tokenizer::TYPE_END)) {
+        return true;
+      }
+
+      DO(ConsumeField(reflection, descriptor));
+    }
+  }
+
+  void ReportError(int line, int col, const string& message) {
+    if (error_collector_ == NULL) {
+      if (line >= 0) {
+        GOOGLE_LOG(ERROR) << "Error parsing text-format "
+                   << root_message_type_->full_name()
+                   << ": " << (line + 1) << ":"
+                   << (col + 1) << ": " << message;
+      } else {
+        GOOGLE_LOG(ERROR) << "Error parsing text-format "
+                   << root_message_type_->full_name()
+                   << ": " << message;
+      }
+    } else {
+      error_collector_->AddError(line, col, message);
+    }
+  }
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl);
+
+  // Reports an error with the given message with information indicating
+  // the position (as derived from the current token).
+  void ReportError(const string& message) {
+    ReportError(tokenizer_.current().line, tokenizer_.current().column,
+                message);
+  }
+
+  // Consumes the specified message with the given starting delimeter.
+  // 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));
+    }
+
+    // Confirm that we have a valid ending delimeter.
+    DO(Consume(delimeter));
+
+    return true;
+  }
+
+  // Consumes the current field (as returned by the tokenizer) on the
+  // passed in message.
+  bool ConsumeField(Message::Reflection* reflection,
+                    const Descriptor* descriptor) {
+    string field_name;
+
+    const FieldDescriptor* field = NULL;
+
+    if (TryConsume("[")) {
+      // Extension.
+      DO(ConsumeIdentifier(&field_name));
+      while (TryConsume(".")) {
+        string part;
+        DO(ConsumeIdentifier(&part));
+        field_name += ".";
+        field_name += part;
+      }
+      DO(Consume("]"));
+
+      field = reflection->FindKnownExtensionByName(field_name);
+
+      if (field == NULL) {
+        ReportError("Extension \"" + field_name + "\" is not defined or "
+                    "is not an extension of \"" +
+                    descriptor->full_name() + "\".");
+        return false;
+      }
+    } else {
+      DO(ConsumeIdentifier(&field_name));
+
+      field = descriptor->FindFieldByName(field_name);
+      // Group names are expected to be capitalized as they appear in the
+      // .proto file, which actually matches their type names, not their field
+      // names.
+      if (field == NULL) {
+        string lower_field_name = field_name;
+        LowerString(&lower_field_name);
+        field = descriptor->FindFieldByName(lower_field_name);
+        // If the case-insensitive match worked but the field is NOT a group,
+        if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) {
+          field = NULL;
+        }
+      }
+      // Again, special-case group names as described above.
+      if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP
+          && field->message_type()->name() != field_name) {
+        field = NULL;
+      }
+
+      if (field == NULL) {
+        ReportError("Message type \"" + descriptor->full_name() +
+                    "\" has no field named \"" + field_name + "\".");
+        return false;
+      }
+    }
+
+    // Perform special handling for embedded message types.
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      string delimeter;
+
+      // ':' is optional here.
+      TryConsume(":");
+
+      if (TryConsume("<")) {
+        delimeter = ">";
+      } else {
+        DO(Consume("{"));
+        delimeter = "}";
+      }
+
+      if (field->is_repeated()) {
+        DO(ConsumeMessage(reflection->AddMessage(field), delimeter));
+      } else {
+        DO(ConsumeMessage(reflection->MutableMessage(field), delimeter));
+      }
+    } else {
+      DO(Consume(":"));
+      DO(ConsumeFieldValue(reflection, field));
+    }
+
+    return true;
+  }
+
+  bool ConsumeFieldValue(Message::Reflection* reflection,
+                         const FieldDescriptor* field) {
+
+// Define an easy to use macro for setting fields. This macro checks
+// to see if the field is repeated (in which case we need to use the Add
+// 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);                  \
+        } else {                                                   \
+          reflection->Set##CPPTYPE(field, VALUE);                  \
+        }                                                          \
+
+    switch(field->cpp_type()) {
+      case FieldDescriptor::CPPTYPE_INT32: {
+        int64 value;
+        DO(ConsumeSignedInteger(&value, kint32max));
+        SET_FIELD(Int32, static_cast<int32>(value));
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_UINT32: {
+        uint64 value;
+        DO(ConsumeUnsignedInteger(&value, kuint32max));
+        SET_FIELD(UInt32, static_cast<uint32>(value));
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_INT64: {
+        int64 value;
+        DO(ConsumeSignedInteger(&value, kint64max));
+        SET_FIELD(Int64, value);
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_UINT64: {
+        uint64 value;
+        DO(ConsumeUnsignedInteger(&value, kuint64max));
+        SET_FIELD(UInt64, value);
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_FLOAT: {
+        double value;
+        DO(ConsumeDouble(&value));
+        SET_FIELD(Float, static_cast<float>(value));
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_DOUBLE: {
+        double value;
+        DO(ConsumeDouble(&value));
+        SET_FIELD(Double, value);
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_STRING: {
+        string value;
+        DO(ConsumeString(&value));
+        SET_FIELD(String, value);
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_BOOL: {
+        string value;
+        DO(ConsumeIdentifier(&value));
+
+        if (value == "true") {
+          SET_FIELD(Bool, true);
+        } else if (value == "false") {
+          SET_FIELD(Bool, false);
+        } else {
+          ReportError("Invalid value for boolean field \"" + field->name()
+                      + "\". Value: \"" + value  + "\".");
+          return false;
+        }
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_ENUM: {
+        string value;
+        DO(ConsumeIdentifier(&value));
+
+        // Find the enumeration value.
+        const EnumDescriptor* enum_type = field->enum_type();
+        const EnumValueDescriptor* enum_value
+            = enum_type->FindValueByName(value);
+
+        if (enum_value == NULL) {
+          ReportError("Unknown enumeration value of \"" + value  + "\" for "
+                      "field \"" + field->name() + "\".");
+          return false;
+        }
+
+        SET_FIELD(Enum, enum_value);
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_MESSAGE: {
+        // We should never get here. Put here instead of a default
+        // so that if new types are added, we get a nice compiler warning.
+        GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE";
+        break;
+      }
+    }
+#undef SET_FIELD
+    return true;
+  }
+
+  // Returns true if the current token's text is equal to that specified.
+  bool LookingAt(const string& text) {
+    return tokenizer_.current().text == text;
+  }
+
+  // Returns true if the current token's type is equal to that specified.
+  bool LookingAtType(io::Tokenizer::TokenType token_type) {
+    return tokenizer_.current().type == token_type;
+  }
+
+  // Consumes an identifier and saves its value in the identifier parameter.
+  // Returns false if the token is not of type IDENTFIER.
+  bool ConsumeIdentifier(string* identifier) {
+    if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+      ReportError("Expected identifier.");
+      return false;
+    }
+
+    *identifier = tokenizer_.current().text;
+
+    tokenizer_.Next();
+    return true;
+  }
+
+  // Consumes a string and saves its value in the text parameter.
+  // Returns false if the token is not of type STRING.
+  bool ConsumeString(string* text) {
+    if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
+      ReportError("Expected string.");
+      return false;
+    }
+
+    io::Tokenizer::ParseString(tokenizer_.current().text, text);
+
+    tokenizer_.Next();
+    return true;
+  }
+
+  // Consumes a uint64 and saves its value in the value parameter.
+  // Returns false if the token is not of type INTEGER.
+  bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
+    if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+      ReportError("Expected integer.");
+      return false;
+    }
+
+    if (!io::Tokenizer::ParseInteger(tokenizer_.current().text,
+                                     max_value, value)) {
+      ReportError("Integer out of range.");
+      return false;
+    }
+
+    tokenizer_.Next();
+    return true;
+  }
+
+  // Consumes an int64 and saves its value in the value parameter.
+  // Note that since the tokenizer does not support negative numbers,
+  // we actually may consume an additional token (for the minus sign) in this
+  // method. Returns false if the token is not an integer
+  // (signed or otherwise).
+  bool ConsumeSignedInteger(int64* value, uint64 max_value) {
+    bool negative = false;
+
+    if (TryConsume("-")) {
+      negative = true;
+      // Two's complement always allows one more negative integer than
+      // positive.
+      ++max_value;
+    }
+
+    uint64 unsigned_value;
+
+    DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
+
+    *value = static_cast<int64>(unsigned_value);
+
+    if (negative) {
+      *value = -*value;
+    }
+
+    return true;
+  }
+
+  // Consumes a double and saves its value in the value parameter.
+  // Note that since the tokenizer does not support negative numbers,
+  // we actually may consume an additional token (for the minus sign) in this
+  // method. Returns false if the token is not a double
+  // (signed or otherwise).
+  bool ConsumeDouble(double* value) {
+    bool negative = false;
+
+    if (TryConsume("-")) {
+      negative = true;
+    }
+
+    // A double can actually be an integer, according to the tokenizer.
+    // Therefore, we must check both cases here.
+    if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+      // We have found an integer value for the double.
+      uint64 integer_value;
+      DO(ConsumeUnsignedInteger(&integer_value, kuint64max));
+
+      *value = static_cast<double>(integer_value);
+    } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
+      // We have found a float value for the double.
+      *value = io::Tokenizer::ParseFloat(tokenizer_.current().text);
+
+      // Mark the current token as consumed.
+      tokenizer_.Next();
+    } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+      string text = tokenizer_.current().text;
+      LowerString(&text);
+      if (text == "inf" || text == "infinity") {
+        *value = std::numeric_limits<double>::infinity();
+        tokenizer_.Next();
+      } else if (text == "nan") {
+        *value = std::numeric_limits<double>::quiet_NaN();
+        tokenizer_.Next();
+      } else {
+        ReportError("Expected double.");
+        return false;
+      }
+    } else {
+      ReportError("Expected double.");
+      return false;
+    }
+
+    if (negative) {
+      *value = -*value;
+    }
+
+    return true;
+  }
+
+  // Consumes a token and confirms that it matches that specified in the
+  // value parameter. Returns false if the token found does not match that
+  // which was specified.
+  bool Consume(const string& value) {
+    const string& current_value = tokenizer_.current().text;
+
+    if (current_value != value) {
+      ReportError("Expected \"" + value + "\", found \"" + current_value
+                  + "\".");
+      return false;
+    }
+
+    tokenizer_.Next();
+
+    return true;
+  }
+
+  // Attempts to consume the supplied value. Returns false if a the
+  // token found does not match the value specified.
+  bool TryConsume(const string& value) {
+    if (tokenizer_.current().text == value) {
+      tokenizer_.Next();
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  // An internal instance of the Tokenizer's error collector, used to
+  // collect any base-level parse errors and feed them to the ParserImpl.
+  class ParserErrorCollector : public io::ErrorCollector {
+   public:
+    explicit ParserErrorCollector(TextFormat::ParserImpl* parser) :
+        parser_(parser) { }
+
+    virtual ~ParserErrorCollector() { };
+
+    virtual void AddError(int line, int column, const string& message) {
+      parser_->ReportError(line, column, message);
+    }
+
+   private:
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
+    TextFormat::ParserImpl* parser_;
+  };
+
+  io::ErrorCollector* error_collector_;
+  ParserErrorCollector tokenizer_error_collector_;
+  io::Tokenizer tokenizer_;
+  const Descriptor* root_message_type_;
+};
+
+#undef DO
+
+// ===========================================================================
+// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
+// from the Printer found in //google/protobuf/io/printer.h
+class TextFormat::TextGenerator {
+ public:
+  explicit TextGenerator(io::ZeroCopyOutputStream* output)
+    : output_(output),
+      buffer_(NULL),
+      buffer_size_(0),
+      at_start_of_line_(true),
+      failed_(false),
+      indent_("") {
+  }
+
+  ~TextGenerator() {
+    // Only BackUp() if we're sure we've successfully called Next() at least
+    // once.
+    if (buffer_size_ > 0) {
+      output_->BackUp(buffer_size_);
+    }
+  }
+
+  // Indent text by two spaces.  After calling Indent(), two spaces will be
+  // inserted at the beginning of each line of text.  Indent() may be called
+  // multiple times to produce deeper indents.
+  void Indent() {
+    indent_ += "  ";
+  }
+
+  // Reduces the current indent level by two spaces, or crashes if the indent
+  // level is zero.
+  void Outdent() {
+    if (indent_.empty()) {
+      GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
+      return;
+    }
+
+    indent_.resize(indent_.size() - 2);
+  }
+
+  // Print text to the output stream.
+  void Print(const string& str) {
+    Print(str.c_str());
+  }
+
+  // Print text to the output stream.
+  void Print(const char* text) {
+    int size = strlen(text);
+    int pos = 0;  // The number of bytes we've written so far.
+
+    for (int i = 0; i < size; i++) {
+      if (text[i] == '\n') {
+        // Saw newline.  If there is more text, we may need to insert an indent
+        // here.  So, write what we have so far, including the '\n'.
+        Write(text + pos, i - pos + 1);
+        pos = i + 1;
+
+        // Setting this true will cause the next Write() to insert an indent
+        // first.
+        at_start_of_line_ = true;
+      }
+    }
+
+    // Write the rest.
+    Write(text + pos, size - pos);
+  }
+
+  // True if any write to the underlying stream failed.  (We don't just
+  // crash in this case because this is an I/O failure, not a programming
+  // error.)
+  bool failed() const { return failed_; }
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
+
+  void Write(const char* data, int size) {
+    if (failed_) return;
+    if (size == 0) return;
+
+    if (at_start_of_line_) {
+      // Insert an indent.
+      at_start_of_line_ = false;
+      Write(indent_.data(), indent_.size());
+      if (failed_) return;
+    }
+
+    while (size > buffer_size_) {
+      // Data exceeds space in the buffer.  Copy what we can and request a
+      // new buffer.
+      memcpy(buffer_, data, buffer_size_);
+      data += buffer_size_;
+      size -= buffer_size_;
+      void* void_buffer;
+      failed_ = !output_->Next(&void_buffer, &buffer_size_);
+      if (failed_) return;
+      buffer_ = reinterpret_cast<char*>(void_buffer);
+    }
+
+    // Buffer is big enough to receive the data; copy it.
+    memcpy(buffer_, data, size);
+    buffer_ += size;
+    buffer_size_ -= size;
+  }
+
+  io::ZeroCopyOutputStream* const output_;
+  char* buffer_;
+  int buffer_size_;
+  bool at_start_of_line_;
+  bool failed_;
+
+  string indent_;
+};
+
+// ===========================================================================
+
+TextFormat::Parser::Parser()
+  : error_collector_(NULL),
+    allow_partial_(false) {}
+
+TextFormat::Parser::~Parser() {}
+
+bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
+                               Message* output) {
+  output->Clear();
+  return Merge(input, output);
+}
+
+bool TextFormat::Parser::ParseFromString(const string& input,
+                                         Message* output) {
+  io::ArrayInputStream input_stream(input.data(), input.size());
+  return Parse(&input_stream, output);
+}
+
+bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
+                               Message* output) {
+  ParserImpl parser(input, error_collector_);
+  if (!parser.Parse(output)) return false;
+  if (!allow_partial_ && !output->IsInitialized()) {
+    vector<string> missing_fields;
+    output->FindInitializationErrors(&missing_fields);
+    parser.ReportError(-1, 0, "Message missing required fields: " +
+                              JoinStrings(missing_fields, ", "));
+    return false;
+  }
+  return true;
+}
+
+bool TextFormat::Parser::MergeFromString(const string& input,
+                                         Message* output) {
+  io::ArrayInputStream input_stream(input.data(), input.size());
+  return Merge(&input_stream, output);
+}
+
+
+/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
+                                    Message* output) {
+  return Parser().Parse(input, output);
+}
+
+/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
+                                    Message* output) {
+  return Parser().Merge(input, output);
+}
+
+/* static */ bool TextFormat::ParseFromString(const string& input,
+                                              Message* output) {
+  return Parser().ParseFromString(input, output);
+}
+
+/* static */ bool TextFormat::MergeFromString(const string& input,
+                                              Message* output) {
+  return Parser().MergeFromString(input, output);
+}
+
+/* static */ bool TextFormat::PrintToString(const Message& message,
+                                            string* output) {
+  GOOGLE_DCHECK(output) << "output specified is NULL";
+
+  output->clear();
+  io::StringOutputStream output_stream(output);
+
+  bool result = Print(message, &output_stream);
+
+  return result;
+}
+
+/* static */ bool TextFormat::Print(const Message& message,
+                                    io::ZeroCopyOutputStream* output) {
+  TextGenerator generator(output);
+
+  Print(message.GetDescriptor(), message.GetReflection(), generator);
+
+  // Output false if the generator failed internally.
+  return !generator.failed();
+}
+
+/* static */ void TextFormat::Print(const Descriptor* descriptor,
+                                    const Message::Reflection* message,
+                                    TextGenerator& generator) {
+  vector<const FieldDescriptor*> fields;
+  message->ListFields(&fields);
+  for (int i = 0; i < fields.size(); i++) {
+    PrintField(fields[i], message, generator);
+  }
+  PrintUnknownFields(message->GetUnknownFields(), generator);
+}
+
+/* static */ void TextFormat::PrintFieldValueToString(
+    const Message& message,
+    const FieldDescriptor* field,
+    int index,
+    string* output) {
+
+  GOOGLE_DCHECK(output) << "output specified is NULL";
+
+  output->clear();
+  io::StringOutputStream output_stream(output);
+  TextGenerator generator(&output_stream);
+
+  PrintFieldValue(message.GetReflection(), field, index, generator);
+}
+
+/* static */ void TextFormat::PrintField(const FieldDescriptor* field,
+                                         const Message::Reflection* message,
+                                         TextGenerator& generator) {
+  int count = 0;
+
+  if (field->is_repeated()) {
+    count = message->FieldSize(field);
+  } else if (message->HasField(field)) {
+    count = 1;
+  }
+
+  for (int j = 0; j < count; ++j) {
+    if (field->is_extension()) {
+      generator.Print("[");
+      // We special-case MessageSet elements for compatibility with proto1.
+      if (field->containing_type()->options().message_set_wire_format()
+          && field->type() == FieldDescriptor::TYPE_MESSAGE
+          && field->is_optional()
+          && field->extension_scope() == field->message_type()) {
+        generator.Print(field->message_type()->full_name());
+      } else {
+        generator.Print(field->full_name());
+      }
+      generator.Print("]");
+    } else {
+      if (field->type() == FieldDescriptor::TYPE_GROUP) {
+        // Groups must be serialized with their original capitalization.
+        generator.Print(field->message_type()->name());
+      } else {
+        generator.Print(field->name());
+      }
+    }
+
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+        generator.Print(" {\n");
+        generator.Indent();
+    } else {
+      generator.Print(": ");
+    }
+
+    // Write the field value.
+    int field_index = j;
+    if (!field->is_repeated()) {
+      field_index = -1;
+    }
+
+    PrintFieldValue(message, field, field_index, generator);
+
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+        generator.Outdent();
+        generator.Print("}");
+    }
+
+    generator.Print("\n");
+  }
+}
+
+/* static */ void TextFormat::PrintFieldValue(
+    const Message::Reflection* reflection,
+    const FieldDescriptor* field,
+    int index,
+    TextGenerator& generator) {
+  GOOGLE_DCHECK(field->is_repeated() || (index == -1))
+      << "Index must be -1 for non-repeated fields";
+
+  switch (field->cpp_type()) {
+#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)));                   \
+        break;                                                               \
+
+      OUTPUT_FIELD( INT32,  Int32, SimpleItoa);
+      OUTPUT_FIELD( INT64,  Int64, SimpleItoa);
+      OUTPUT_FIELD(UINT32, UInt32, SimpleItoa);
+      OUTPUT_FIELD(UINT64, UInt64, SimpleItoa);
+      OUTPUT_FIELD( FLOAT,  Float, SimpleFtoa);
+      OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa);
+#undef OUTPUT_FIELD
+
+      case FieldDescriptor::CPPTYPE_STRING: {
+        string scratch;
+        const string& value = field->is_repeated() ?
+            reflection->GetRepeatedStringReference(field, index, &scratch) :
+            reflection->GetStringReference(field, &scratch);
+
+        generator.Print("\"");
+        generator.Print(CEscape(value));
+        generator.Print("\"");
+
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_BOOL:
+        if (field->is_repeated()) {
+          generator.Print(reflection->GetRepeatedBool(field, index)
+                          ? "true" : "false");
+        } else {
+          generator.Print(reflection->GetBool(field) ? "true" : "false");
+        }
+        break;
+
+      case FieldDescriptor::CPPTYPE_ENUM:
+        generator.Print(field->is_repeated() ?
+                        reflection->GetRepeatedEnum(field, index)->name()
+                        : reflection->GetEnum(field)->name());
+        break;
+
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        Print(field->message_type(),
+              field->is_repeated() ?
+              reflection->GetRepeatedMessage(field, index).GetReflection()
+              : reflection->GetMessage(field).GetReflection(), generator);
+        break;
+  }
+}
+
+// Prints an integer as hex with a fixed number of digits dependent on the
+// integer type.
+template<typename IntType>
+static string PaddedHex(IntType value) {
+  string result;
+  result.reserve(sizeof(value) * 2);
+  for (int i = sizeof(value) * 2 - 1; i >= 0; i--) {
+    result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F));
+  }
+  return result;
+}
+
+/* static */ void TextFormat::PrintUnknownFields(
+    const UnknownFieldSet& unknown_fields, TextGenerator& generator) {
+  for (int i = 0; i < unknown_fields.field_count(); i++) {
+    const UnknownField& field = unknown_fields.field(i);
+    string field_number = SimpleItoa(field.number());
+
+    for (int j = 0; j < field.varint_size(); j++) {
+      generator.Print(field_number);
+      generator.Print(": ");
+      generator.Print(SimpleItoa(field.varint(j)));
+      generator.Print("\n");
+    }
+    for (int j = 0; j < field.fixed32_size(); j++) {
+      generator.Print(field_number);
+      generator.Print(": 0x");
+      char buffer[kFastToBufferSize];
+      generator.Print(FastHex32ToBuffer(field.fixed32(j), buffer));
+      generator.Print("\n");
+    }
+    for (int j = 0; j < field.fixed64_size(); j++) {
+      generator.Print(field_number);
+      generator.Print(": 0x");
+      char buffer[kFastToBufferSize];
+      generator.Print(FastHex64ToBuffer(field.fixed64(j), buffer));
+      generator.Print("\n");
+    }
+    for (int j = 0; j < field.length_delimited_size(); j++) {
+      generator.Print(field_number);
+      generator.Print(": \"");
+      generator.Print(CEscape(field.length_delimited(j)));
+      generator.Print("\"\n");
+    }
+    for (int j = 0; j < field.group_size(); j++) {
+      generator.Print(field_number);
+      generator.Print(" {\n");
+      generator.Indent();
+      PrintUnknownFields(field.group(j), generator);
+      generator.Outdent();
+      generator.Print("}\n");
+    }
+  }
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
new file mode 100644
index 0000000..df27710
--- /dev/null
+++ b/src/google/protobuf/text_format.h
@@ -0,0 +1,143 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: jschorr@google.com (Joseph Schorr)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Utilities for printing and parsing protocol messages in a human-readable,
+// text-based format.
+
+#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__
+#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__
+
+#include <string>
+#include <google/protobuf/message.h>  // Message, Message::Reflection
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+
+namespace io {
+  class ErrorCollector;      // tokenizer.h
+}
+
+// This class implements protocol buffer text format.  Printing and parsing
+// protocol messages in text format is useful for debugging and human editing
+// of messages.
+//
+// This class is really a namespace that contains only static methods.
+class LIBPROTOBUF_EXPORT TextFormat {
+ public:
+  // Outputs a textual representation of the given message to the given
+  // output stream.
+  static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
+  // Like Print(), but outputs directly to a string.
+  static bool PrintToString(const Message& message, string* output);
+
+  // Outputs a textual representation of the value of the field supplied on
+  // the message supplied. For non-repeated fields, an index of -1 must
+  // be supplied. Note that this method will print the default value for a
+  // field if it is not set.
+  static void PrintFieldValueToString(const Message& message,
+                                      const FieldDescriptor* field,
+                                      int index,
+                                      string* output);
+
+  // Parses a text-format protocol message from the given input stream to
+  // the given message object.  This function parses the format written
+  // by Print().
+  static bool Parse(io::ZeroCopyInputStream* input, Message* output);
+  // Like Parse(), but reads directly from a string.
+  static bool ParseFromString(const string& input, Message* output);
+
+  // Like Parse(), but the data is merged into the given message, as if
+  // using Message::MergeFrom().
+  static bool Merge(io::ZeroCopyInputStream* input, Message* output);
+  // Like Merge(), but reads directly from a string.
+  static bool MergeFromString(const string& input, Message* output);
+
+  // For more control over parsing, use this class.
+  class LIBPROTOBUF_EXPORT Parser {
+   public:
+    Parser();
+    ~Parser();
+
+    // Like TextFormat::Parse().
+    bool Parse(io::ZeroCopyInputStream* input, Message* output);
+    // Like TextFormat::ParseFromString().
+    bool ParseFromString(const string& input, Message* output);
+    // Like TextFormat::Merge().
+    bool Merge(io::ZeroCopyInputStream* input, Message* output);
+    // Like TextFormat::MergeFromString().
+    bool MergeFromString(const string& input, Message* output);
+
+    // Set where to report parse errors.  If NULL (the default), errors will
+    // be printed to stderr.
+    void RecordErrorsTo(io::ErrorCollector* error_collector) {
+      error_collector_ = error_collector;
+    }
+
+    // Normally parsing fails if, after parsing, output->IsInitialized()
+    // returns false.  Call AllowPartialMessage(true) to skip this check.
+    void AllowPartialMessage(bool allow) {
+      allow_partial_ = allow;
+    }
+
+   private:
+    io::ErrorCollector* error_collector_;
+    bool allow_partial_;
+  };
+
+ private:
+  // Forward declaration of an internal class used to print the text
+  // output to the OutputStream (see text_format.cc for implementation).
+  class TextGenerator;
+
+  // Forward declaration of an internal class used to parse text
+  // representations (see text_format.cc for implementation).
+  class ParserImpl;
+
+  // Internal Print method, used for writing to the OutputStream via
+  // the TextGenerator class.
+  static void Print(const Descriptor* descriptor,
+                    const Message::Reflection* message,
+                    TextGenerator& generator);
+
+  // Print a single field.
+  static void PrintField(const FieldDescriptor* field,
+                         const Message::Reflection* message,
+                         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,
+                              const FieldDescriptor* field,
+                              int index,
+                              TextGenerator& generator);
+
+  // Print the fields in an UnknownFieldSet.  They are printed by tag number
+  // only.
+  static void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
+                                 TextGenerator& generator);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
new file mode 100644
index 0000000..48c7076
--- /dev/null
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -0,0 +1,697 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: jschorr@google.com (Joseph Schorr)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <math.h>
+#include <stdlib.h>
+#include <limits>
+
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_mset.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+inline bool IsNaN(double value) {
+  // NaN is never equal to anything, even itself.
+  return value != value;
+}
+
+// A basic string with different escapable characters for testing.
+const string kEscapeTestString =
+  "\"A string with ' characters \n and \r newlines and \t tabs and \001 "
+  "slashes \\";
+
+// A representation of the above string with all the characters escaped.
+const string kEscapeTestStringEscaped =
+  "\"\\\"A string with \\' characters \\n and \\r newlines "
+  "and \\t tabs and \\001 slashes \\\\\"";
+
+class TextFormatTest : public testing::Test {
+ public:
+  static void SetUpTestCase() {
+    File::ReadFileToStringOrDie(
+        TestSourceDir()
+        + "/google/protobuf/testdata/text_format_unittest_data.txt",
+        &static_proto_debug_string_);
+  }
+
+  TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {}
+
+ protected:
+  // Debug string read from text_format_unittest_data.txt.
+  const string proto_debug_string_;
+  unittest::TestAllTypes proto_;
+
+ private:
+  static string static_proto_debug_string_;
+};
+string TextFormatTest::static_proto_debug_string_;
+
+class TextFormatExtensionsTest : public testing::Test {
+ public:
+  static void SetUpTestCase() {
+    File::ReadFileToStringOrDie(
+        TestSourceDir()
+        + "/google/protobuf/testdata/"
+          "text_format_unittest_extensions_data.txt",
+        &static_proto_debug_string_);
+  }
+
+  TextFormatExtensionsTest()
+      : proto_debug_string_(static_proto_debug_string_) {}
+
+ protected:
+  // Debug string read from text_format_unittest_data.txt.
+  const string proto_debug_string_;
+  unittest::TestAllExtensions proto_;
+
+ private:
+  static string static_proto_debug_string_;
+};
+string TextFormatExtensionsTest::static_proto_debug_string_;
+
+
+TEST_F(TextFormatTest, Basic) {
+  TestUtil::SetAllFields(&proto_);
+  EXPECT_EQ(proto_debug_string_, proto_.DebugString());
+}
+
+TEST_F(TextFormatExtensionsTest, Extensions) {
+  TestUtil::SetAllExtensions(&proto_);
+  EXPECT_EQ(proto_debug_string_, proto_.DebugString());
+}
+
+TEST_F(TextFormatTest, StringEscape) {
+  // Set the string value to test.
+  proto_.set_optional_string(kEscapeTestString);
+
+  // Get the DebugString from the proto.
+  string debug_string = proto_.DebugString();
+
+  // Hardcode a correct value to test against.
+  string correct_string = "optional_string: "
+      + kEscapeTestStringEscaped
+       + "\n";
+
+  // Compare.
+  EXPECT_EQ(correct_string, debug_string);
+}
+
+TEST_F(TextFormatTest, PrintUnknownFields) {
+  // Test printing of unknown fields in a message.
+
+  unittest::TestEmptyMessage message;
+  UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
+  UnknownField* field5 = unknown_fields->AddField(5);
+
+  field5->add_varint(1);
+  field5->add_fixed32(2);
+  field5->add_fixed64(3);
+  field5->add_length_delimited("4");
+  field5->add_group()->AddField(10)->add_varint(5);
+
+  UnknownField* field8 = unknown_fields->AddField(8);
+  field8->add_varint(1);
+  field8->add_varint(2);
+  field8->add_varint(3);
+
+  EXPECT_EQ(
+    "5: 1\n"
+    "5: 0x00000002\n"
+    "5: 0x0000000000000003\n"
+    "5: \"4\"\n"
+    "5 {\n"
+    "  10: 5\n"
+    "}\n"
+    "8: 1\n"
+    "8: 2\n"
+    "8: 3\n",
+    message.DebugString());
+}
+
+TEST_F(TextFormatTest, ParseBasic) {
+  io::ArrayInputStream input_stream(proto_debug_string_.data(),
+                                    proto_debug_string_.size());
+  TextFormat::Parse(&input_stream, &proto_);
+  TestUtil::ExpectAllFieldsSet(proto_);
+}
+
+TEST_F(TextFormatExtensionsTest, ParseExtensions) {
+  io::ArrayInputStream input_stream(proto_debug_string_.data(),
+                                    proto_debug_string_.size());
+  TextFormat::Parse(&input_stream, &proto_);
+  TestUtil::ExpectAllExtensionsSet(proto_);
+}
+
+TEST_F(TextFormatTest, ParseStringEscape) {
+  // Create a parse string with escpaed characters in it.
+  string parse_string = "optional_string: "
+      + kEscapeTestStringEscaped
+      + "\n";
+
+  io::ArrayInputStream input_stream(parse_string.data(),
+                                    parse_string.size());
+  TextFormat::Parse(&input_stream, &proto_);
+
+  // Compare.
+  EXPECT_EQ(kEscapeTestString, proto_.optional_string());
+}
+
+TEST_F(TextFormatTest, ParseFloatWithSuffix) {
+  // Test that we can parse a floating-point value with 'f' appended to the
+  // end.  This is needed for backwards-compatibility with proto1.
+
+  // Have it parse a float with the 'f' suffix.
+  string parse_string = "optional_float: 1.0f\n";
+
+  io::ArrayInputStream input_stream(parse_string.data(),
+                                    parse_string.size());
+
+  TextFormat::Parse(&input_stream, &proto_);
+
+  // Compare.
+  EXPECT_EQ(1.0, proto_.optional_float());
+}
+
+TEST_F(TextFormatTest, Comments) {
+  // Test that comments are ignored.
+
+  string parse_string = "optional_int32: 1  # a comment\n"
+                        "optional_int64: 2  # another comment";
+
+  io::ArrayInputStream input_stream(parse_string.data(),
+                                    parse_string.size());
+
+  TextFormat::Parse(&input_stream, &proto_);
+
+  // Compare.
+  EXPECT_EQ(1, proto_.optional_int32());
+  EXPECT_EQ(2, proto_.optional_int64());
+}
+
+TEST_F(TextFormatTest, OptionalColon) {
+  // Test that we can place a ':' after the field name of a nested message,
+  // even though we don't have to.
+
+  string parse_string = "optional_nested_message: { bb: 1}\n";
+
+  io::ArrayInputStream input_stream(parse_string.data(),
+                                    parse_string.size());
+
+  TextFormat::Parse(&input_stream, &proto_);
+
+  // Compare.
+  EXPECT_TRUE(proto_.has_optional_nested_message());
+  EXPECT_EQ(1, proto_.optional_nested_message().bb());
+}
+
+// Some platforms (e.g. Windows) insist on padding the exponent to three
+// digits when one or two would be just fine.
+static string RemoveRedundantZeros(string text) {
+  text = StringReplace(text, "e+0", "e+", true);
+  text = StringReplace(text, "e-0", "e-", true);
+  return text;
+}
+
+TEST_F(TextFormatTest, PrintExotic) {
+  unittest::TestAllTypes message;
+
+  // Note:  In C, a negative integer literal is actually the unary negation
+  //   operator being applied to a positive integer literal, and
+  //   9223372036854775808 is outside the range of int64.  However, it is not
+  //   outside the range of uint64.  Confusingly, this means that everything
+  //   works if we make the literal unsigned, even though we are negating it.
+  message.add_repeated_int64(-GOOGLE_ULONGLONG(9223372036854775808));
+  message.add_repeated_uint64(GOOGLE_ULONGLONG(18446744073709551615));
+  message.add_repeated_double(123.456);
+  message.add_repeated_double(1.23e21);
+  message.add_repeated_double(1.23e-18);
+  message.add_repeated_double(std::numeric_limits<double>::infinity());
+  message.add_repeated_double(-std::numeric_limits<double>::infinity());
+  message.add_repeated_double(std::numeric_limits<double>::quiet_NaN());
+  message.add_repeated_string(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12));
+
+  // Fun story:  We used to use 1.23e22 instead of 1.23e21 above, but this
+  //   seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of
+  //   the value differed from strtod()'s parsing.  That is to say, the
+  //   following assertion fails on MinGW:
+  //     assert(1.23e22 == strtod("1.23e22", NULL));
+  //   As a result, SimpleDtoa() would print the value as
+  //   "1.2300000000000001e+22" to make sure strtod() produce the exact same
+  //   result.  Our goal is to test runtime parsing, not compile-time parsing,
+  //   so this wasn't our problem.  It was found that using 1.23e21 did not
+  //   have this problem, so we switched to that instead.
+
+  EXPECT_EQ(
+    "repeated_int64: -9223372036854775808\n"
+    "repeated_uint64: 18446744073709551615\n"
+    "repeated_double: 123.456\n"
+    "repeated_double: 1.23e+21\n"
+    "repeated_double: 1.23e-18\n"
+    "repeated_double: inf\n"
+    "repeated_double: -inf\n"
+    "repeated_double: nan\n"
+    "repeated_string: \"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n",
+    RemoveRedundantZeros(message.DebugString()));
+}
+
+TEST_F(TextFormatTest, PrintFloatPrecision) {
+  unittest::TestAllTypes message;
+
+  message.add_repeated_float(1.2);
+  message.add_repeated_float(1.23);
+  message.add_repeated_float(1.234);
+  message.add_repeated_float(1.2345);
+  message.add_repeated_float(1.23456);
+  message.add_repeated_float(1.2e10);
+  message.add_repeated_float(1.23e10);
+  message.add_repeated_float(1.234e10);
+  message.add_repeated_float(1.2345e10);
+  message.add_repeated_float(1.23456e10);
+  message.add_repeated_double(1.2);
+  message.add_repeated_double(1.23);
+  message.add_repeated_double(1.234);
+  message.add_repeated_double(1.2345);
+  message.add_repeated_double(1.23456);
+  message.add_repeated_double(1.234567);
+  message.add_repeated_double(1.2345678);
+  message.add_repeated_double(1.23456789);
+  message.add_repeated_double(1.234567898);
+  message.add_repeated_double(1.2345678987);
+  message.add_repeated_double(1.23456789876);
+  message.add_repeated_double(1.234567898765);
+  message.add_repeated_double(1.2345678987654);
+  message.add_repeated_double(1.23456789876543);
+  message.add_repeated_double(1.2e100);
+  message.add_repeated_double(1.23e100);
+  message.add_repeated_double(1.234e100);
+  message.add_repeated_double(1.2345e100);
+  message.add_repeated_double(1.23456e100);
+  message.add_repeated_double(1.234567e100);
+  message.add_repeated_double(1.2345678e100);
+  message.add_repeated_double(1.23456789e100);
+  message.add_repeated_double(1.234567898e100);
+  message.add_repeated_double(1.2345678987e100);
+  message.add_repeated_double(1.23456789876e100);
+  message.add_repeated_double(1.234567898765e100);
+  message.add_repeated_double(1.2345678987654e100);
+  message.add_repeated_double(1.23456789876543e100);
+
+  EXPECT_EQ(
+    "repeated_float: 1.2\n"
+    "repeated_float: 1.23\n"
+    "repeated_float: 1.234\n"
+    "repeated_float: 1.2345\n"
+    "repeated_float: 1.23456\n"
+    "repeated_float: 1.2e+10\n"
+    "repeated_float: 1.23e+10\n"
+    "repeated_float: 1.234e+10\n"
+    "repeated_float: 1.2345e+10\n"
+    "repeated_float: 1.23456e+10\n"
+    "repeated_double: 1.2\n"
+    "repeated_double: 1.23\n"
+    "repeated_double: 1.234\n"
+    "repeated_double: 1.2345\n"
+    "repeated_double: 1.23456\n"
+    "repeated_double: 1.234567\n"
+    "repeated_double: 1.2345678\n"
+    "repeated_double: 1.23456789\n"
+    "repeated_double: 1.234567898\n"
+    "repeated_double: 1.2345678987\n"
+    "repeated_double: 1.23456789876\n"
+    "repeated_double: 1.234567898765\n"
+    "repeated_double: 1.2345678987654\n"
+    "repeated_double: 1.23456789876543\n"
+    "repeated_double: 1.2e+100\n"
+    "repeated_double: 1.23e+100\n"
+    "repeated_double: 1.234e+100\n"
+    "repeated_double: 1.2345e+100\n"
+    "repeated_double: 1.23456e+100\n"
+    "repeated_double: 1.234567e+100\n"
+    "repeated_double: 1.2345678e+100\n"
+    "repeated_double: 1.23456789e+100\n"
+    "repeated_double: 1.234567898e+100\n"
+    "repeated_double: 1.2345678987e+100\n"
+    "repeated_double: 1.23456789876e+100\n"
+    "repeated_double: 1.234567898765e+100\n"
+    "repeated_double: 1.2345678987654e+100\n"
+    "repeated_double: 1.23456789876543e+100\n",
+    RemoveRedundantZeros(message.DebugString()));
+}
+
+
+TEST_F(TextFormatTest, AllowPartial) {
+  unittest::TestRequired message;
+  TextFormat::Parser parser;
+  parser.AllowPartialMessage(true);
+  EXPECT_TRUE(parser.ParseFromString("a: 1", &message));
+  EXPECT_EQ(1, message.a());
+  EXPECT_FALSE(message.has_b());
+  EXPECT_FALSE(message.has_c());
+}
+
+TEST_F(TextFormatTest, ParseExotic) {
+  unittest::TestAllTypes message;
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "repeated_int32: -1\n"
+    "repeated_int32: -2147483648\n"
+    "repeated_int64: -1\n"
+    "repeated_int64: -9223372036854775808\n"
+    "repeated_uint32: 4294967295\n"
+    "repeated_uint32: 2147483648\n"
+    "repeated_uint64: 18446744073709551615\n"
+    "repeated_uint64: 9223372036854775808\n"
+    "repeated_double: 123.0\n"
+    "repeated_double: 123.5\n"
+    "repeated_double: 0.125\n"
+    "repeated_double: 1.23E17\n"
+    "repeated_double: 1.235E+22\n"
+    "repeated_double: 1.235e-18\n"
+    "repeated_double: 123.456789\n"
+    "repeated_double: inf\n"
+    "repeated_double: Infinity\n"
+    "repeated_double: -inf\n"
+    "repeated_double: -Infinity\n"
+    "repeated_double: nan\n"
+    "repeated_double: NaN\n"
+    "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n",
+    &message));
+
+  ASSERT_EQ(2, message.repeated_int32_size());
+  EXPECT_EQ(-1, message.repeated_int32(0));
+  // Note:  In C, a negative integer literal is actually the unary negation
+  //   operator being applied to a positive integer literal, and 2147483648 is
+  //   outside the range of int32.  However, it is not outside the range of
+  //   uint32.  Confusingly, this means that everything works if we make the
+  //   literal unsigned, even though we are negating it.
+  EXPECT_EQ(-2147483648u, message.repeated_int32(1));
+
+  ASSERT_EQ(2, message.repeated_int64_size());
+  EXPECT_EQ(-1, message.repeated_int64(0));
+  // Note:  In C, a negative integer literal is actually the unary negation
+  //   operator being applied to a positive integer literal, and
+  //   9223372036854775808 is outside the range of int64.  However, it is not
+  //   outside the range of uint64.  Confusingly, this means that everything
+  //   works if we make the literal unsigned, even though we are negating it.
+  EXPECT_EQ(-GOOGLE_ULONGLONG(9223372036854775808), message.repeated_int64(1));
+
+  ASSERT_EQ(2, message.repeated_uint32_size());
+  EXPECT_EQ(4294967295u, message.repeated_uint32(0));
+  EXPECT_EQ(2147483648u, message.repeated_uint32(1));
+
+  ASSERT_EQ(2, message.repeated_uint64_size());
+  EXPECT_EQ(GOOGLE_ULONGLONG(18446744073709551615), message.repeated_uint64(0));
+  EXPECT_EQ(GOOGLE_ULONGLONG(9223372036854775808), message.repeated_uint64(1));
+
+  ASSERT_EQ(13, message.repeated_double_size());
+  EXPECT_EQ(123.0     , message.repeated_double(0));
+  EXPECT_EQ(123.5     , message.repeated_double(1));
+  EXPECT_EQ(0.125     , message.repeated_double(2));
+  EXPECT_EQ(1.23E17   , message.repeated_double(3));
+  EXPECT_EQ(1.235E22  , message.repeated_double(4));
+  EXPECT_EQ(1.235E-18 , message.repeated_double(5));
+  EXPECT_EQ(123.456789, message.repeated_double(6));
+  EXPECT_EQ(message.repeated_double(7), numeric_limits<double>::infinity());
+  EXPECT_EQ(message.repeated_double(8), numeric_limits<double>::infinity());
+  EXPECT_EQ(message.repeated_double(9), -numeric_limits<double>::infinity());
+  EXPECT_EQ(message.repeated_double(10), -numeric_limits<double>::infinity());
+  EXPECT_TRUE(IsNaN(message.repeated_double(11)));
+  EXPECT_TRUE(IsNaN(message.repeated_double(12)));
+
+  // Note:  Since these string literals have \0's in them, we must explicitly
+  //   pass their sizes to string's constructor.
+  ASSERT_EQ(1, message.repeated_string_size());
+  EXPECT_EQ(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12),
+            message.repeated_string(0));
+}
+
+class TextFormatParserTest : public testing::Test {
+ protected:
+  void ExpectFailure(const string& input, const string& message, int line,
+                     int col) {
+    unittest::TestAllTypes proto;
+    ExpectFailure(input, message, line, col, &proto);
+  }
+
+  void ExpectFailure(const string& input, const string& message, int line,
+                     int col, Message* proto) {
+    TextFormat::Parser parser;
+    MockErrorCollector error_collector;
+    parser.RecordErrorsTo(&error_collector);
+    EXPECT_FALSE(parser.ParseFromString(input, proto));
+    EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n",
+              error_collector.text_);
+  }
+
+  // An error collector which simply concatenates all its errors into a big
+  // block of text which can be checked.
+  class MockErrorCollector : public io::ErrorCollector {
+   public:
+    MockErrorCollector() {}
+    ~MockErrorCollector() {}
+
+    string text_;
+
+    // implements ErrorCollector -------------------------------------
+    void AddError(int line, int column, const string& message) {
+      strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
+                                   line + 1, column + 1, message);
+    }
+  };
+};
+
+TEST_F(TextFormatParserTest, InvalidToken) {
+  ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.",
+                2, 1);
+
+  ExpectFailure("optional_bool: true;\n", "Expected identifier.", 1, 20);
+  ExpectFailure("\"some string\"", "Expected identifier.", 1, 1);
+}
+
+TEST_F(TextFormatParserTest, InvalidFieldName) {
+  ExpectFailure(
+      "invalid_field: somevalue\n",
+      "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+      "\"invalid_field\".",
+      1, 14);
+}
+
+TEST_F(TextFormatParserTest, InvalidCapitalization) {
+  // We require that group names be exactly as they appear in the .proto.
+  ExpectFailure(
+      "optionalgroup {\na: 15\n}\n",
+      "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+      "\"optionalgroup\".",
+      1, 15);
+  ExpectFailure(
+      "OPTIONALgroup {\na: 15\n}\n",
+      "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+      "\"OPTIONALgroup\".",
+      1, 15);
+  ExpectFailure(
+      "Optional_Double: 10.0\n",
+      "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+      "\"Optional_Double\".",
+      1, 16);
+}
+
+TEST_F(TextFormatParserTest, InvalidFieldValues) {
+  // Invalid values for a double/float field.
+  ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18);
+  ExpectFailure("optional_double: true\n", "Expected double.", 1, 18);
+  ExpectFailure("optional_double: !\n", "Expected double.", 1, 18);
+  ExpectFailure("optional_double {\n  \n}\n", "Expected \":\", found \"{\".",
+                1, 17);
+
+  // Invalid values for a signed integer field.
+  ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17);
+  ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17);
+  ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17);
+  ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17);
+  ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".",
+                1, 16);
+  ExpectFailure("optional_int32: 0x80000000\n",
+                "Integer out of range.", 1, 17);
+  ExpectFailure("optional_int32: -0x80000001\n",
+                "Integer out of range.", 1, 18);
+  ExpectFailure("optional_int64: 0x8000000000000000\n",
+                "Integer out of range.", 1, 17);
+  ExpectFailure("optional_int64: -0x8000000000000001\n",
+                "Integer out of range.", 1, 18);
+
+  // Invalid values for an unsigned integer field.
+  ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18);
+  ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18);
+  ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18);
+  ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18);
+  ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18);
+  ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".",
+                1, 17);
+  ExpectFailure("optional_uint32: 0x100000000\n",
+                "Integer out of range.", 1, 18);
+  ExpectFailure("optional_uint64: 0x10000000000000000\n",
+                "Integer out of range.", 1, 18);
+
+  // Invalid values for a boolean field.
+  ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16);
+  ExpectFailure("optional_bool: 5\n", "Expected identifier.", 1, 16);
+  ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16);
+  ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16);
+
+  ExpectFailure(
+      "optional_bool: meh\n",
+      "Invalid value for boolean field \"optional_bool\". Value: \"meh\".",
+      2, 1);
+
+  ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".",
+                1, 15);
+
+  // Invalid values for a string field.
+  ExpectFailure("optional_string: true\n", "Expected string.", 1, 18);
+  ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18);
+  ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18);
+  ExpectFailure("optional_string: !\n", "Expected string.", 1, 18);
+  ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".",
+                1, 17);
+
+  // Invalid values for an enumeration field.
+  ExpectFailure("optional_nested_enum: \"hello\"\n", "Expected identifier.",
+                1, 23);
+
+  ExpectFailure("optional_nested_enum: 5\n", "Expected identifier.", 1, 23);
+  ExpectFailure("optional_nested_enum: -7.5\n", "Expected identifier.", 1, 23);
+  ExpectFailure("optional_nested_enum: !\n", "Expected identifier.", 1, 23);
+
+  ExpectFailure(
+      "optional_nested_enum: grah\n",
+      "Unknown enumeration value of \"grah\" for field "
+      "\"optional_nested_enum\".", 2, 1);
+
+ ExpectFailure(
+      "optional_nested_enum {\n \n}\n",
+      "Expected \":\", found \"{\".", 1, 22);
+}
+
+TEST_F(TextFormatParserTest, MessageDelimeters) {
+  // Non-matching delimeters.
+  ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".",
+                3, 1);
+
+  // Invalid delimeters.
+  ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".",
+                1, 15);
+
+  // Unending message.
+  ExpectFailure("optional_nested_message {\n \nbb: 118\n",
+                "Expected identifier.",
+                4, 1);
+}
+
+TEST_F(TextFormatParserTest, UnknownExtension) {
+  // Non-matching delimeters.
+  ExpectFailure("[blahblah]: 123",
+                "Extension \"blahblah\" is not defined or is not an "
+                "extension of \"protobuf_unittest.TestAllTypes\".",
+                1, 11);
+}
+
+TEST_F(TextFormatParserTest, MissingRequired) {
+  unittest::TestRequired message;
+  ExpectFailure("a: 1",
+                "Message missing required fields: b, c",
+                0, 1, &message);
+}
+
+TEST_F(TextFormatParserTest, PrintErrorsToStderr) {
+  vector<string> errors;
+
+  {
+    ScopedMemoryLog log;
+    unittest::TestAllTypes proto;
+    EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto));
+    errors = log.GetMessages(ERROR);
+  }
+
+  ASSERT_EQ(1, errors.size());
+  EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: "
+            "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field "
+            "named \"no_such_field\".",
+            errors[0]);
+}
+
+
+class TextFormatMessageSetTest : public testing::Test {
+ protected:
+  static const char proto_debug_string_[];
+};
+const char TextFormatMessageSetTest::proto_debug_string_[] =
+"message_set {\n"
+"  [protobuf_unittest.TestMessageSetExtension1] {\n"
+"    i: 23\n"
+"  }\n"
+"  [protobuf_unittest.TestMessageSetExtension2] {\n"
+"    str: \"foo\"\n"
+"  }\n"
+"}\n";
+
+
+TEST_F(TextFormatMessageSetTest, Serialize) {
+  protobuf_unittest::TestMessageSetContainer proto;
+  protobuf_unittest::TestMessageSetExtension1* item_a =
+    proto.mutable_message_set()->MutableExtension(
+      protobuf_unittest::TestMessageSetExtension1::message_set_extension);
+  item_a->set_i(23);
+  protobuf_unittest::TestMessageSetExtension2* item_b =
+    proto.mutable_message_set()->MutableExtension(
+      protobuf_unittest::TestMessageSetExtension2::message_set_extension);
+  item_b->set_str("foo");
+  EXPECT_EQ(proto_debug_string_, proto.DebugString());
+}
+
+TEST_F(TextFormatMessageSetTest, Deserialize) {
+  protobuf_unittest::TestMessageSetContainer proto;
+  ASSERT_TRUE(TextFormat::ParseFromString(proto_debug_string_, &proto));
+  EXPECT_EQ(23, proto.message_set().GetExtension(
+    protobuf_unittest::TestMessageSetExtension1::message_set_extension).i());
+  EXPECT_EQ("foo", proto.message_set().GetExtension(
+    protobuf_unittest::TestMessageSetExtension2::message_set_extension).str());
+
+  // Ensure that these are the only entries present.
+  vector<const FieldDescriptor*> descriptors;
+  proto.message_set().GetReflection()->ListFields(&descriptors);
+  EXPECT_EQ(2, descriptors.size());
+}
+
+} // namespace
+}  // namespace protobuf
+
+}  // namespace google
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto
new file mode 100644
index 0000000..f65c431
--- /dev/null
+++ b/src/google/protobuf/unittest.proto
@@ -0,0 +1,452 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+
+import "google/protobuf/unittest_import.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestProto";
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+  message NestedMessage {
+    // The field name "b" fails to compile in proto1 because it conflicts with
+    // a local variable named "b" in one of the generated methods.  Doh.
+    // This file needs to compile in proto1 to test backwards-compatibility.
+    optional int32 bb = 1;
+  }
+
+  enum NestedEnum {
+    FOO = 1;
+    BAR = 2;
+    BAZ = 3;
+  }
+
+  // Singular
+  optional    int32 optional_int32    =  1;
+  optional    int64 optional_int64    =  2;
+  optional   uint32 optional_uint32   =  3;
+  optional   uint64 optional_uint64   =  4;
+  optional   sint32 optional_sint32   =  5;
+  optional   sint64 optional_sint64   =  6;
+  optional  fixed32 optional_fixed32  =  7;
+  optional  fixed64 optional_fixed64  =  8;
+  optional sfixed32 optional_sfixed32 =  9;
+  optional sfixed64 optional_sfixed64 = 10;
+  optional    float optional_float    = 11;
+  optional   double optional_double   = 12;
+  optional     bool optional_bool     = 13;
+  optional   string optional_string   = 14;
+  optional    bytes optional_bytes    = 15;
+
+  optional group OptionalGroup = 16 {
+    optional int32 a = 17;
+  }
+
+  optional NestedMessage                        optional_nested_message  = 18;
+  optional ForeignMessage                       optional_foreign_message = 19;
+  optional protobuf_unittest_import.ImportMessage optional_import_message  = 20;
+
+  optional NestedEnum                           optional_nested_enum     = 21;
+  optional ForeignEnum                          optional_foreign_enum    = 22;
+  optional protobuf_unittest_import.ImportEnum    optional_import_enum     = 23;
+
+  optional string optional_string_piece = 24 [ctype=STRING_PIECE];
+  optional string optional_cord = 25 [ctype=CORD];
+
+  // Repeated
+  repeated    int32 repeated_int32    = 31;
+  repeated    int64 repeated_int64    = 32;
+  repeated   uint32 repeated_uint32   = 33;
+  repeated   uint64 repeated_uint64   = 34;
+  repeated   sint32 repeated_sint32   = 35;
+  repeated   sint64 repeated_sint64   = 36;
+  repeated  fixed32 repeated_fixed32  = 37;
+  repeated  fixed64 repeated_fixed64  = 38;
+  repeated sfixed32 repeated_sfixed32 = 39;
+  repeated sfixed64 repeated_sfixed64 = 40;
+  repeated    float repeated_float    = 41;
+  repeated   double repeated_double   = 42;
+  repeated     bool repeated_bool     = 43;
+  repeated   string repeated_string   = 44;
+  repeated    bytes repeated_bytes    = 45;
+
+  repeated group RepeatedGroup = 46 {
+    optional int32 a = 47;
+  }
+
+  repeated NestedMessage                        repeated_nested_message  = 48;
+  repeated ForeignMessage                       repeated_foreign_message = 49;
+  repeated protobuf_unittest_import.ImportMessage repeated_import_message  = 50;
+
+  repeated NestedEnum                           repeated_nested_enum     = 51;
+  repeated ForeignEnum                          repeated_foreign_enum    = 52;
+  repeated protobuf_unittest_import.ImportEnum    repeated_import_enum     = 53;
+
+  repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+  repeated string repeated_cord = 55 [ctype=CORD];
+
+  // Singular with defaults
+  optional    int32 default_int32    = 61 [default =  41    ];
+  optional    int64 default_int64    = 62 [default =  42    ];
+  optional   uint32 default_uint32   = 63 [default =  43    ];
+  optional   uint64 default_uint64   = 64 [default =  44    ];
+  optional   sint32 default_sint32   = 65 [default = -45    ];
+  optional   sint64 default_sint64   = 66 [default =  46    ];
+  optional  fixed32 default_fixed32  = 67 [default =  47    ];
+  optional  fixed64 default_fixed64  = 68 [default =  48    ];
+  optional sfixed32 default_sfixed32 = 69 [default =  49    ];
+  optional sfixed64 default_sfixed64 = 70 [default = -50    ];
+  optional    float default_float    = 71 [default =  51.5  ];
+  optional   double default_double   = 72 [default =  52e3  ];
+  optional     bool default_bool     = 73 [default = true   ];
+  optional   string default_string   = 74 [default = "hello"];
+  optional    bytes default_bytes    = 75 [default = "world"];
+
+  optional NestedEnum  default_nested_enum  = 81 [default = BAR        ];
+  optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];
+  optional protobuf_unittest_import.ImportEnum
+      default_import_enum = 83 [default = IMPORT_BAR];
+
+  optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+  optional string default_cord = 85 [ctype=CORD,default="123"];
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+  optional int32 c = 1;
+}
+
+enum ForeignEnum {
+  FOREIGN_FOO = 4;
+  FOREIGN_BAR = 5;
+  FOREIGN_BAZ = 6;
+}
+
+message TestAllExtensions {
+  extensions 1 to max;
+}
+
+extend TestAllExtensions {
+  // Singular
+  optional    int32 optional_int32_extension    =  1;
+  optional    int64 optional_int64_extension    =  2;
+  optional   uint32 optional_uint32_extension   =  3;
+  optional   uint64 optional_uint64_extension   =  4;
+  optional   sint32 optional_sint32_extension   =  5;
+  optional   sint64 optional_sint64_extension   =  6;
+  optional  fixed32 optional_fixed32_extension  =  7;
+  optional  fixed64 optional_fixed64_extension  =  8;
+  optional sfixed32 optional_sfixed32_extension =  9;
+  optional sfixed64 optional_sfixed64_extension = 10;
+  optional    float optional_float_extension    = 11;
+  optional   double optional_double_extension   = 12;
+  optional     bool optional_bool_extension     = 13;
+  optional   string optional_string_extension   = 14;
+  optional    bytes optional_bytes_extension    = 15;
+
+  optional group OptionalGroup_extension = 16 {
+    optional int32 a = 17;
+  }
+
+  optional TestAllTypes.NestedMessage optional_nested_message_extension = 18;
+  optional ForeignMessage optional_foreign_message_extension = 19;
+  optional protobuf_unittest_import.ImportMessage
+    optional_import_message_extension = 20;
+
+  optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21;
+  optional ForeignEnum optional_foreign_enum_extension = 22;
+  optional protobuf_unittest_import.ImportEnum
+    optional_import_enum_extension = 23;
+
+  optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE];
+  optional string optional_cord_extension = 25 [ctype=CORD];
+
+  // Repeated
+  repeated    int32 repeated_int32_extension    = 31;
+  repeated    int64 repeated_int64_extension    = 32;
+  repeated   uint32 repeated_uint32_extension   = 33;
+  repeated   uint64 repeated_uint64_extension   = 34;
+  repeated   sint32 repeated_sint32_extension   = 35;
+  repeated   sint64 repeated_sint64_extension   = 36;
+  repeated  fixed32 repeated_fixed32_extension  = 37;
+  repeated  fixed64 repeated_fixed64_extension  = 38;
+  repeated sfixed32 repeated_sfixed32_extension = 39;
+  repeated sfixed64 repeated_sfixed64_extension = 40;
+  repeated    float repeated_float_extension    = 41;
+  repeated   double repeated_double_extension   = 42;
+  repeated     bool repeated_bool_extension     = 43;
+  repeated   string repeated_string_extension   = 44;
+  repeated    bytes repeated_bytes_extension    = 45;
+
+  repeated group RepeatedGroup_extension = 46 {
+    optional int32 a = 47;
+  }
+
+  repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48;
+  repeated ForeignMessage repeated_foreign_message_extension = 49;
+  repeated protobuf_unittest_import.ImportMessage
+    repeated_import_message_extension = 50;
+
+  repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51;
+  repeated ForeignEnum repeated_foreign_enum_extension = 52;
+  repeated protobuf_unittest_import.ImportEnum
+    repeated_import_enum_extension = 53;
+
+  repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE];
+  repeated string repeated_cord_extension = 55 [ctype=CORD];
+
+  // Singular with defaults
+  optional    int32 default_int32_extension    = 61 [default =  41    ];
+  optional    int64 default_int64_extension    = 62 [default =  42    ];
+  optional   uint32 default_uint32_extension   = 63 [default =  43    ];
+  optional   uint64 default_uint64_extension   = 64 [default =  44    ];
+  optional   sint32 default_sint32_extension   = 65 [default = -45    ];
+  optional   sint64 default_sint64_extension   = 66 [default =  46    ];
+  optional  fixed32 default_fixed32_extension  = 67 [default =  47    ];
+  optional  fixed64 default_fixed64_extension  = 68 [default =  48    ];
+  optional sfixed32 default_sfixed32_extension = 69 [default =  49    ];
+  optional sfixed64 default_sfixed64_extension = 70 [default = -50    ];
+  optional    float default_float_extension    = 71 [default =  51.5  ];
+  optional   double default_double_extension   = 72 [default =  52e3  ];
+  optional     bool default_bool_extension     = 73 [default = true   ];
+  optional   string default_string_extension   = 74 [default = "hello"];
+  optional    bytes default_bytes_extension    = 75 [default = "world"];
+
+  optional TestAllTypes.NestedEnum
+    default_nested_enum_extension = 81 [default = BAR];
+  optional ForeignEnum
+    default_foreign_enum_extension = 82 [default = FOREIGN_BAR];
+  optional protobuf_unittest_import.ImportEnum
+    default_import_enum_extension = 83 [default = IMPORT_BAR];
+
+  optional string default_string_piece_extension = 84 [ctype=STRING_PIECE,
+                                                       default="abc"];
+  optional string default_cord_extension = 85 [ctype=CORD, default="123"];
+}
+
+// We have separate messages for testing required fields because it's
+// annoying to have to fill in required fields in TestProto in order to
+// do anything with it.  Note that we don't need to test every type of
+// required filed because the code output is basically identical to
+// optional fields for all types.
+message TestRequired {
+  required int32 a = 1;
+  optional int32 dummy2 = 2;
+  required int32 b = 3;
+
+  extend TestAllExtensions {
+    optional TestRequired single = 1000;
+    repeated TestRequired multi  = 1001;
+  }
+
+  // Pad the field count to 32 so that we can test that IsInitialized()
+  // properly checks multiple elements of has_bits_.
+  optional int32 dummy4  =  4;
+  optional int32 dummy5  =  5;
+  optional int32 dummy6  =  6;
+  optional int32 dummy7  =  7;
+  optional int32 dummy8  =  8;
+  optional int32 dummy9  =  9;
+  optional int32 dummy10 = 10;
+  optional int32 dummy11 = 11;
+  optional int32 dummy12 = 12;
+  optional int32 dummy13 = 13;
+  optional int32 dummy14 = 14;
+  optional int32 dummy15 = 15;
+  optional int32 dummy16 = 16;
+  optional int32 dummy17 = 17;
+  optional int32 dummy18 = 18;
+  optional int32 dummy19 = 19;
+  optional int32 dummy20 = 20;
+  optional int32 dummy21 = 21;
+  optional int32 dummy22 = 22;
+  optional int32 dummy23 = 23;
+  optional int32 dummy24 = 24;
+  optional int32 dummy25 = 25;
+  optional int32 dummy26 = 26;
+  optional int32 dummy27 = 27;
+  optional int32 dummy28 = 28;
+  optional int32 dummy29 = 29;
+  optional int32 dummy30 = 30;
+  optional int32 dummy31 = 31;
+  optional int32 dummy32 = 32;
+
+  required int32 c = 33;
+}
+
+message TestRequiredForeign {
+  optional TestRequired optional_message = 1;
+  repeated TestRequired repeated_message = 2;
+  optional int32 dummy = 3;
+}
+
+// Test that we can use NestedMessage from outside TestAllTypes.
+message TestForeignNested {
+  optional TestAllTypes.NestedMessage foreign_nested = 1;
+}
+
+// TestEmptyMessage is used to test unknown field support.
+message TestEmptyMessage {
+}
+
+// Like above, but declare all field numbers as potential extensions.  No
+// actual extensions should ever be defined for this type.
+message TestEmptyMessageWithExtensions {
+  extensions 1 to max;
+}
+
+// Test that really large tag numbers don't break anything.
+message TestReallyLargeTagNumber {
+  // The largest possible tag number is 2^28 - 1, since the wire format uses
+  // three bits to communicate wire type.
+  optional int32 a = 1;
+  optional int32 bb = 268435455;
+}
+
+message TestRecursiveMessage {
+  optional TestRecursiveMessage a = 1;
+  optional int32 i = 2;
+}
+
+// Test that mutual recursion works.
+message TestMutualRecursionA {
+  optional TestMutualRecursionB bb = 1;
+}
+
+message TestMutualRecursionB {
+  optional TestMutualRecursionA a = 1;
+  optional int32 optional_int32 = 2;
+}
+
+// Test that groups have disjoint field numbers from their siblings and
+// parents.  This is NOT possible in proto1; only proto2.  When outputting
+// proto1, the dup fields should be dropped.
+message TestDupFieldNumber {
+  optional int32 a = 1;
+  optional group Foo = 2 { optional int32 a = 1; }
+  optional group Bar = 3 { optional int32 a = 1; }
+}
+
+
+// Needed for a Python test.
+message TestNestedMessageHasBits {
+  message NestedMessage {
+    repeated int32 nestedmessage_repeated_int32 = 1;
+    repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2;
+  }
+  optional NestedMessage optional_nested_message = 1;
+}
+
+
+// Test an enum that has multiple values with the same number.
+enum TestEnumWithDupValue {
+  FOO1 = 1;
+  BAR1 = 2;
+  BAZ = 3;
+  FOO2 = 1;
+  BAR2 = 2;
+}
+
+// Test an enum with large, unordered values.
+enum TestSparseEnum {
+  SPARSE_A = 123;
+  SPARSE_B = 62374;
+  SPARSE_C = 12589234;
+  SPARSE_D = -15;
+  SPARSE_E = -53452;
+  SPARSE_F = 0;
+  SPARSE_G = 2;
+}
+
+// Test message with CamelCase field names.  This violates Protocol Buffer
+// standard style.
+message TestCamelCaseFieldNames {
+  optional int32 PrimitiveField = 1;
+  optional string StringField = 2;
+  optional ForeignEnum EnumField = 3;
+  optional ForeignMessage MessageField = 4;
+  optional string StringPieceField = 5 [ctype=STRING_PIECE];
+  optional string CordField = 6 [ctype=CORD];
+
+  repeated int32 RepeatedPrimitiveField = 7;
+  repeated string RepeatedStringField = 8;
+  repeated ForeignEnum RepeatedEnumField = 9;
+  repeated ForeignMessage RepeatedMessageField = 10;
+  repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE];
+  repeated string RepeatedCordField = 12 [ctype=CORD];
+}
+
+
+// We list fields out of order, to ensure that we're using field number and not
+// field index to determine serialization order.
+message TestFieldOrderings {
+  optional string my_string = 11;
+  extensions 2 to 10;
+  optional int64 my_int = 1;
+  extensions 12 to 100;
+  optional float my_float = 101;
+}
+
+
+extend TestFieldOrderings {
+  optional string my_extension_string = 50;
+  optional int32 my_extension_int = 5;
+}
+
+
+message TestExtremeDefaultValues {
+  optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"];
+  optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF];
+  optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF];
+  optional  int32 small_int32  = 4 [default = -0x7FFFFFFF];
+  optional  int64 small_int64  = 5 [default = -0x7FFFFFFFFFFFFFFF];
+
+  // The default value here is UTF-8 for "\u1234".  (We could also just type
+  // the UTF-8 text directly into this text file rather than escape it, but
+  // lots of people use editors that would be confused by this.)
+  optional string utf8_string = 6 [default = "\341\210\264"];
+}
+
+// Test that RPC services work.
+message FooRequest  {}
+message FooResponse {}
+
+service TestService {
+  rpc Foo(FooRequest) returns (FooResponse);
+  rpc Bar(BarRequest) returns (BarResponse);
+}
+
+
+message BarRequest  {}
+message BarResponse {}
diff --git a/src/google/protobuf/unittest_embed_optimize_for.proto b/src/google/protobuf/unittest_embed_optimize_for.proto
new file mode 100644
index 0000000..c600d9f
--- /dev/null
+++ b/src/google/protobuf/unittest_embed_optimize_for.proto
@@ -0,0 +1,36 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which imports a proto file that uses optimize_for = CODE_SIZE.
+
+import "google/protobuf/unittest_optimize_for.proto";
+
+package protobuf_unittest;
+
+// We optimize for speed here, but we are importing a proto that is optimized
+// for code size.
+option optimize_for = SPEED;
+
+message TestEmbedOptimizedForSize {
+  // Test that embedding a message which has optimize_for = CODE_SIZE into
+  // one optimized for speed works.
+  optional TestOptimizedForSize optional_message = 1;
+  repeated TestOptimizedForSize repeated_message = 2;
+}
diff --git a/src/google/protobuf/unittest_import.proto b/src/google/protobuf/unittest_import.proto
new file mode 100644
index 0000000..58ce42c
--- /dev/null
+++ b/src/google/protobuf/unittest_import.proto
@@ -0,0 +1,47 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which is imported by unittest.proto to test importing.
+
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do
+// "using namespace unittest_import = protobuf_unittest_import".
+package protobuf_unittest_import;
+
+option optimize_for = SPEED;
+
+// Excercise the java_package option.
+option java_package = "com.google.protobuf.test";
+
+// Do not set a java_outer_classname here to verify that Proto2 works without
+// one.
+
+message ImportMessage {
+  optional int32 d = 1;
+}
+
+enum ImportEnum {
+  IMPORT_FOO = 7;
+  IMPORT_BAR = 8;
+  IMPORT_BAZ = 9;
+}
+
diff --git a/src/google/protobuf/unittest_mset.proto b/src/google/protobuf/unittest_mset.proto
new file mode 100644
index 0000000..455086d
--- /dev/null
+++ b/src/google/protobuf/unittest_mset.proto
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains messages for testing message_set_wire_format.
+
+package protobuf_unittest;
+
+option optimize_for = SPEED;
+
+// A message with message_set_wire_format.
+message TestMessageSet {
+  option message_set_wire_format = true;
+  extensions 4 to max;
+}
+
+message TestMessageSetContainer {
+  optional TestMessageSet message_set = 1;
+}
+
+message TestMessageSetExtension1 {
+  extend TestMessageSet {
+    optional TestMessageSetExtension1 message_set_extension = 1545008;
+  }
+  optional int32 i = 15;
+}
+
+message TestMessageSetExtension2 {
+  extend TestMessageSet {
+    optional TestMessageSetExtension2 message_set_extension = 1547769;
+  }
+  optional string str = 25;
+}
+
+// MessageSet wire format is equivalent to this.
+message RawMessageSet {
+  repeated group Item = 1 {
+    required int32 type_id = 2;
+    required bytes message = 3;
+  }
+}
+
diff --git a/src/google/protobuf/unittest_optimize_for.proto b/src/google/protobuf/unittest_optimize_for.proto
new file mode 100644
index 0000000..6154e9c
--- /dev/null
+++ b/src/google/protobuf/unittest_optimize_for.proto
@@ -0,0 +1,38 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which uses optimize_for = CODE_SIZE.
+
+import "google/protobuf/unittest.proto";
+
+package protobuf_unittest;
+
+option optimize_for = CODE_SIZE;
+
+message TestOptimizedForSize {
+  optional int32 i = 1;
+  optional ForeignMessage msg = 19;
+
+  extensions 1000 to max;
+
+  extend TestOptimizedForSize {
+    optional int32 test_extension = 1234;
+  }
+}
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc
new file mode 100644
index 0000000..2f44901
--- /dev/null
+++ b/src/google/protobuf/unknown_field_set.cc
@@ -0,0 +1,112 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+
+UnknownFieldSet::UnknownFieldSet()
+  : internal_(NULL) {}
+
+UnknownFieldSet::~UnknownFieldSet() {
+  if (internal_ != NULL) {
+    STLDeleteValues(&internal_->fields_);
+    delete internal_;
+  }
+}
+
+void UnknownFieldSet::Clear() {
+  if (internal_ == NULL) return;
+
+  if (internal_->fields_.size() > kMaxInactiveFields) {
+    STLDeleteValues(&internal_->fields_);
+  } else {
+    // Don't delete the UnknownField objects.  Just remove them from the active
+    // set.
+    for (int i = 0; i < internal_->active_fields_.size(); i++) {
+      internal_->active_fields_[i]->Clear();
+      internal_->active_fields_[i]->index_ = -1;
+    }
+  }
+
+  internal_->active_fields_.clear();
+}
+
+void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) {
+  for (int i = 0; i < other.field_count(); i++) {
+    AddField(other.field(i).number())->MergeFrom(other.field(i));
+  }
+}
+
+const UnknownField* UnknownFieldSet::FindFieldByNumber(int number) const {
+  if (internal_ == NULL) return NULL;
+
+  map<int, UnknownField*>::iterator iter = internal_->fields_.find(number);
+  if (iter != internal_->fields_.end() && iter->second->index() != -1) {
+    return iter->second;
+  } else {
+    return NULL;
+  }
+}
+
+UnknownField* UnknownFieldSet::AddField(int number) {
+  if (internal_ == NULL) internal_ = new Internal;
+
+  UnknownField** map_slot = &internal_->fields_[number];
+  if (*map_slot == NULL) {
+    *map_slot = new UnknownField(number);
+  }
+
+  UnknownField* field = *map_slot;
+  if (field->index() == -1) {
+    field->index_ = internal_->active_fields_.size();
+    internal_->active_fields_.push_back(field);
+  }
+  return field;
+}
+
+UnknownField::UnknownField(int number)
+  : number_(number),
+    index_(-1) {
+}
+
+UnknownField::~UnknownField() {
+}
+
+void UnknownField::Clear() {
+  clear_varint();
+  clear_fixed32();
+  clear_fixed64();
+  clear_length_delimited();
+  clear_group();
+}
+
+void UnknownField::MergeFrom(const UnknownField& other) {
+  varint_          .MergeFrom(other.varint_          );
+  fixed32_         .MergeFrom(other.fixed32_         );
+  fixed64_         .MergeFrom(other.fixed64_         );
+  length_delimited_.MergeFrom(other.length_delimited_);
+  group_           .MergeFrom(other.group_           );
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
new file mode 100644
index 0000000..4218462
--- /dev/null
+++ b/src/google/protobuf/unknown_field_set.h
@@ -0,0 +1,322 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Contains classes used to keep track of unrecognized fields seen while
+// parsing a protocol message.
+
+#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
+#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
+
+#include <string>
+#include <map>
+#include <vector>
+#include <google/protobuf/repeated_field.h>
+
+namespace google {
+namespace protobuf {
+
+class Message;                      // message.h
+class UnknownField;                 // below
+
+// An UnknownFieldSet contains fields that were encountered while parsing a
+// message but were not defined by its type.  Keeping track of these can be
+// useful, especially in that they may be written if the message is serialized
+// again without being cleared in between.  This means that software which
+// simply receives messages and forwards them to other servers does not need
+// 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().
+//
+// This class is necessarily tied to the protocol buffer wire format, unlike
+// the Reflection interface which is independent of any serialization scheme.
+class LIBPROTOBUF_EXPORT UnknownFieldSet {
+ public:
+  UnknownFieldSet();
+  ~UnknownFieldSet();
+
+  // Remove all fields.
+  void Clear();
+
+  // Is this set empty?
+  inline bool empty() const;
+
+  // Merge the contents of some other UnknownFieldSet with this one.
+  void MergeFrom(const UnknownFieldSet& other);
+
+  // Returns the number of fields present in the UnknownFieldSet.
+  inline int field_count() const;
+  // Get a field in the set, where 0 <= index < field_count().  The fields
+  // appear in arbitrary order.
+  inline const UnknownField& field(int index) const;
+  // Get a mutable pointer to a field in the set, where
+  // 0 <= index < field_count().  The fields appear in arbitrary order.
+  inline UnknownField* mutable_field(int index);
+
+  // Find a field by field number.  Returns NULL if not found.
+  const UnknownField* FindFieldByNumber(int number) const;
+
+  // Add a field by field number.  If the field number already exists, returns
+  // the existing UnknownField.
+  UnknownField* AddField(int number);
+
+ private:
+  // "Active" fields are ones which have been added since the last time Clear()
+  // was called.  Inactive fields are objects we are keeping around incase
+  // they become active again.
+
+  struct Internal {
+    // Contains all UnknownFields that have been allocated for this
+    // UnknownFieldSet, including ones not currently active.  Keyed by
+    // field number.  We intentionally try to reuse UnknownField objects for
+    // the same field number they were used for originally because this makes
+    // it more likely that the previously-allocated memory will have the right
+    // layout.
+    map<int, UnknownField*> fields_;
+
+    // Contains the fields from fields_ that are currently active.
+    vector<UnknownField*> active_fields_;
+  };
+
+  // We want an UnknownFieldSet to use no more space than a single pointer
+  // until the first field is added.
+  Internal* internal_;
+
+  // Don't keep more inactive fields than this.
+  static const int kMaxInactiveFields = 100;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
+};
+
+// Represents one field in an UnknownFieldSet.
+//
+// UnknownFiled's accessors are similar to those that would be produced by the
+// protocol compiler for the fields:
+//   repeated uint64 varint;
+//   repeated fixed32 fixed32;
+//   repeated fixed64 fixed64;
+//   repeated bytes length_delimited;
+//   repeated UnknownFieldSet group;
+// (OK, so the last one isn't actually a valid field type but you get the
+// idea.)
+class LIBPROTOBUF_EXPORT UnknownField {
+ public:
+  ~UnknownField();
+
+  // Clears all fields.
+  void Clear();
+
+  // Merge the contents of some other UnknownField with this one.  For each
+  // wire type, the values are simply concatenated.
+  void MergeFrom(const UnknownField& other);
+
+  // The field's tag number, as seen on the wire.
+  inline int number() const;
+
+  // The index of this UnknownField within the UknownFieldSet (e.g.
+  // set.field(field.index()) == field).
+  inline int index() const;
+
+  inline int varint_size          () const;
+  inline int fixed32_size         () const;
+  inline int fixed64_size         () const;
+  inline int length_delimited_size() const;
+  inline int group_size           () const;
+
+  inline uint64 varint (int index) const;
+  inline uint32 fixed32(int index) const;
+  inline uint64 fixed64(int index) const;
+  inline const string& length_delimited(int index) const;
+  inline const UnknownFieldSet& group(int index) const;
+
+  inline void set_varint (int index, uint64 value);
+  inline void set_fixed32(int index, uint32 value);
+  inline void set_fixed64(int index, uint64 value);
+  inline void set_length_delimited(int index, const string& value);
+  inline string* mutable_length_delimited(int index);
+  inline UnknownFieldSet* mutable_group(int index);
+
+  inline void add_varint (uint64 value);
+  inline void add_fixed32(uint32 value);
+  inline void add_fixed64(uint64 value);
+  inline void add_length_delimited(const string& value);
+  inline string* add_length_delimited();
+  inline UnknownFieldSet* add_group();
+
+  inline void clear_varint ();
+  inline void clear_fixed32();
+  inline void clear_fixed64();
+  inline void clear_length_delimited();
+  inline void clear_group();
+
+  inline const RepeatedField   <uint64         >& varint          () const;
+  inline const RepeatedField   <uint32         >& fixed32         () const;
+  inline const RepeatedField   <uint64         >& fixed64         () const;
+  inline const RepeatedPtrField<string         >& length_delimited() const;
+  inline const RepeatedPtrField<UnknownFieldSet>& group           () const;
+
+  inline RepeatedField   <uint64         >* mutable_varint          ();
+  inline RepeatedField   <uint32         >* mutable_fixed32         ();
+  inline RepeatedField   <uint64         >* mutable_fixed64         ();
+  inline RepeatedPtrField<string         >* mutable_length_delimited();
+  inline RepeatedPtrField<UnknownFieldSet>* mutable_group           ();
+
+ private:
+  friend class UnknownFieldSet;
+  UnknownField(int number);
+
+  int number_;
+  int index_;
+
+  RepeatedField   <uint64         > varint_;
+  RepeatedField   <uint32         > fixed32_;
+  RepeatedField   <uint64         > fixed64_;
+  RepeatedPtrField<string         > length_delimited_;
+  RepeatedPtrField<UnknownFieldSet> group_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownField);
+};
+
+// ===================================================================
+// inline implementations
+
+inline bool UnknownFieldSet::empty() const {
+  return internal_ == NULL || internal_->active_fields_.empty();
+}
+
+inline int UnknownFieldSet::field_count() const {
+  return (internal_ == NULL) ? 0 : internal_->active_fields_.size();
+}
+inline const UnknownField& UnknownFieldSet::field(int index) const {
+  return *(internal_->active_fields_[index]);
+}
+inline UnknownField* UnknownFieldSet::mutable_field(int index) {
+  return internal_->active_fields_[index];
+}
+
+inline int UnknownField::number() const { return number_; }
+inline int UnknownField::index () const { return index_; }
+
+inline int UnknownField::varint_size          () const {return varint_.size();}
+inline int UnknownField::fixed32_size         () const {return fixed32_.size();}
+inline int UnknownField::fixed64_size         () const {return fixed64_.size();}
+inline int UnknownField::length_delimited_size() const {
+  return length_delimited_.size();
+}
+inline int UnknownField::group_size           () const {return group_.size();}
+
+inline uint64 UnknownField::varint (int index) const {
+  return varint_.Get(index);
+}
+inline uint32 UnknownField::fixed32(int index) const {
+  return fixed32_.Get(index);
+}
+inline uint64 UnknownField::fixed64(int index) const {
+  return fixed64_.Get(index);
+}
+inline const string& UnknownField::length_delimited(int index) const {
+  return length_delimited_.Get(index);
+}
+inline const UnknownFieldSet& UnknownField::group(int index) const {
+  return group_.Get(index);
+}
+
+inline void UnknownField::set_varint (int index, uint64 value) {
+  varint_.Set(index, value);
+}
+inline void UnknownField::set_fixed32(int index, uint32 value) {
+  fixed32_.Set(index, value);
+}
+inline void UnknownField::set_fixed64(int index, uint64 value) {
+  fixed64_.Set(index, value);
+}
+inline void UnknownField::set_length_delimited(int index, const string& value) {
+  length_delimited_.Mutable(index)->assign(value);
+}
+inline string* UnknownField::mutable_length_delimited(int index) {
+  return length_delimited_.Mutable(index);
+}
+inline UnknownFieldSet* UnknownField::mutable_group(int index) {
+  return group_.Mutable(index);
+}
+
+inline void UnknownField::add_varint (uint64 value) {
+  varint_.Add(value);
+}
+inline void UnknownField::add_fixed32(uint32 value) {
+  fixed32_.Add(value);
+}
+inline void UnknownField::add_fixed64(uint64 value) {
+  fixed64_.Add(value);
+}
+inline void UnknownField::add_length_delimited(const string& value) {
+  length_delimited_.Add()->assign(value);
+}
+inline string* UnknownField::add_length_delimited() {
+  return length_delimited_.Add();
+}
+inline UnknownFieldSet* UnknownField::add_group() {
+  return group_.Add();
+}
+
+inline void UnknownField::clear_varint () { varint_.Clear(); }
+inline void UnknownField::clear_fixed32() { varint_.Clear(); }
+inline void UnknownField::clear_fixed64() { varint_.Clear(); }
+inline void UnknownField::clear_length_delimited() {
+  length_delimited_.Clear();
+}
+inline void UnknownField::clear_group() { group_.Clear(); }
+
+inline const RepeatedField<uint64>& UnknownField::varint () const {
+  return varint_;
+}
+inline const RepeatedField<uint32>& UnknownField::fixed32() const {
+  return fixed32_;
+}
+inline const RepeatedField<uint64>& UnknownField::fixed64() const {
+  return fixed64_;
+}
+inline const RepeatedPtrField<string>& UnknownField::length_delimited() const {
+  return length_delimited_;
+}
+inline const RepeatedPtrField<UnknownFieldSet>& UnknownField::group() const {
+  return group_;
+}
+
+inline RepeatedField<uint64>* UnknownField::mutable_varint () {
+  return &varint_;
+}
+inline RepeatedField<uint32>* UnknownField::mutable_fixed32() {
+  return &fixed32_;
+}
+inline RepeatedField<uint64>* UnknownField::mutable_fixed64() {
+  return &fixed64_;
+}
+inline RepeatedPtrField<string>* UnknownField::mutable_length_delimited() {
+  return &length_delimited_;
+}
+inline RepeatedPtrField<UnknownFieldSet>* UnknownField::mutable_group() {
+  return &group_;
+}
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc
new file mode 100644
index 0000000..39b005f
--- /dev/null
+++ b/src/google/protobuf/unknown_field_set_unittest.cc
@@ -0,0 +1,424 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This test is testing a lot more than just the UnknownFieldSet class.  It
+// tests handling of unknown fields throughout the system.
+
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+using internal::WireFormat;
+
+namespace {
+
+class UnknownFieldSetTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    descriptor_ = unittest::TestAllTypes::descriptor();
+    TestUtil::SetAllFields(&all_fields_);
+    all_fields_.SerializeToString(&all_fields_data_);
+    ASSERT_TRUE(empty_message_.ParseFromString(all_fields_data_));
+    unknown_fields_ = empty_message_.mutable_unknown_fields();
+  }
+
+  const UnknownField* GetField(const string& name) {
+    const FieldDescriptor* field = descriptor_->FindFieldByName(name);
+    if (field == NULL) return NULL;
+    return unknown_fields_->FindFieldByNumber(field->number());
+  }
+
+  // Constructs a protocol buffer which contains fields with all the same
+  // numbers as all_fields_data_ except that each field is some other wire
+  // type.
+  string GetBizarroData() {
+    unittest::TestEmptyMessage bizarro_message;
+    UnknownFieldSet* bizarro_unknown_fields =
+      bizarro_message.mutable_unknown_fields();
+    for (int i = 0; i < unknown_fields_->field_count(); i++) {
+      const UnknownField& unknown_field = unknown_fields_->field(i);
+      UnknownField* bizarro_field =
+        bizarro_unknown_fields->AddField(unknown_field.number());
+      if (unknown_field.varint_size() == 0) {
+        bizarro_field->add_varint(1);
+      } else {
+        bizarro_field->add_fixed32(1);
+      }
+    }
+
+    string data;
+    EXPECT_TRUE(bizarro_message.SerializeToString(&data));
+    return data;
+  }
+
+  const Descriptor* descriptor_;
+  unittest::TestAllTypes all_fields_;
+  string all_fields_data_;
+
+  // An empty message that has been parsed from all_fields_data_.  So, it has
+  // unknown fields of every type.
+  unittest::TestEmptyMessage empty_message_;
+  UnknownFieldSet* unknown_fields_;
+};
+
+TEST_F(UnknownFieldSetTest, Index) {
+  for (int i = 0; i < unknown_fields_->field_count(); i++) {
+    EXPECT_EQ(i, unknown_fields_->field(i).index());
+  }
+}
+
+TEST_F(UnknownFieldSetTest, FindFieldByNumber) {
+  // All fields of TestAllTypes should be present.  Fields that are not valid
+  // field numbers of TestAllTypes should NOT be present.
+
+  for (int i = 0; i < 1000; i++) {
+    if (descriptor_->FindFieldByNumber(i) == NULL) {
+      EXPECT_TRUE(unknown_fields_->FindFieldByNumber(i) == NULL);
+    } else {
+      EXPECT_TRUE(unknown_fields_->FindFieldByNumber(i) != NULL);
+    }
+  }
+}
+
+TEST_F(UnknownFieldSetTest, Varint) {
+  const UnknownField* field = GetField("optional_int32");
+  ASSERT_TRUE(field != NULL);
+
+  ASSERT_EQ(1, field->varint_size());
+  EXPECT_EQ(all_fields_.optional_int32(), field->varint(0));
+}
+
+TEST_F(UnknownFieldSetTest, Fixed32) {
+  const UnknownField* field = GetField("optional_fixed32");
+  ASSERT_TRUE(field != NULL);
+
+  ASSERT_EQ(1, field->fixed32_size());
+  EXPECT_EQ(all_fields_.optional_fixed32(), field->fixed32(0));
+}
+
+TEST_F(UnknownFieldSetTest, Fixed64) {
+  const UnknownField* field = GetField("optional_fixed64");
+  ASSERT_TRUE(field != NULL);
+
+  ASSERT_EQ(1, field->fixed64_size());
+  EXPECT_EQ(all_fields_.optional_fixed64(), field->fixed64(0));
+}
+
+TEST_F(UnknownFieldSetTest, LengthDelimited) {
+  const UnknownField* field = GetField("optional_string");
+  ASSERT_TRUE(field != NULL);
+
+  ASSERT_EQ(1, field->length_delimited_size());
+  EXPECT_EQ(all_fields_.optional_string(), field->length_delimited(0));
+}
+
+TEST_F(UnknownFieldSetTest, Group) {
+  const UnknownField* field = GetField("optionalgroup");
+  ASSERT_TRUE(field != NULL);
+
+  ASSERT_EQ(1, field->group_size());
+  EXPECT_EQ(1, field->group(0).field_count());
+
+  const UnknownField& nested_field = field->group(0).field(0);
+  const FieldDescriptor* nested_field_descriptor =
+    unittest::TestAllTypes::OptionalGroup::descriptor()->FindFieldByName("a");
+  ASSERT_TRUE(nested_field_descriptor != NULL);
+
+  EXPECT_EQ(nested_field_descriptor->number(), nested_field.number());
+  EXPECT_EQ(all_fields_.optionalgroup().a(), nested_field.varint(0));
+}
+
+TEST_F(UnknownFieldSetTest, Serialize) {
+  // Check that serializing the UnknownFieldSet produces the original data
+  // again.
+
+  string data;
+  empty_message_.SerializeToString(&data);
+
+  // Don't use EXPECT_EQ because we don't want to dump raw binary data to
+  // stdout.
+  EXPECT_TRUE(data == all_fields_data_);
+}
+
+TEST_F(UnknownFieldSetTest, ParseViaReflection) {
+  // Make sure fields are properly parsed to the UnknownFieldSet when parsing
+  // via reflection.
+
+  unittest::TestEmptyMessage message;
+  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()));
+
+  EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, SerializeViaReflection) {
+  // Make sure fields are properly written from the UnknownFieldSet when
+  // serializing via reflection.
+
+  string data;
+
+  {
+    io::StringOutputStream raw_output(&data);
+    io::CodedOutputStream output(&raw_output);
+    int size = WireFormat::ByteSize(empty_message_.GetDescriptor(),
+                                    empty_message_.GetReflection());
+    ASSERT_TRUE(
+      WireFormat::SerializeWithCachedSizes(empty_message_.GetDescriptor(),
+                                           empty_message_.GetReflection(),
+                                           size, &output));
+  }
+
+  // Don't use EXPECT_EQ because we don't want to dump raw binary data to
+  // stdout.
+  EXPECT_TRUE(data == all_fields_data_);
+}
+
+TEST_F(UnknownFieldSetTest, CopyFrom) {
+  unittest::TestEmptyMessage message;
+
+  message.CopyFrom(empty_message_);
+
+  EXPECT_EQ(empty_message_.DebugString(), message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, MergeFrom) {
+  unittest::TestEmptyMessage source, destination;
+
+  destination.mutable_unknown_fields()->AddField(1)->add_varint(1);
+  destination.mutable_unknown_fields()->AddField(3)->add_varint(2);
+  source.mutable_unknown_fields()->AddField(2)->add_varint(3);
+  source.mutable_unknown_fields()->AddField(3)->add_varint(4);
+
+  destination.MergeFrom(source);
+
+  EXPECT_EQ(
+    // Note:  The ordering of fields here depends on the ordering of adds
+    //   and merging, above.
+    "1: 1\n"
+    "3: 2\n"
+    "3: 4\n"
+    "2: 3\n",
+    destination.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, Clear) {
+  // Get a pointer to a contained field object.
+  const UnknownField* field = GetField("optional_int32");
+  ASSERT_TRUE(field != NULL);
+  ASSERT_EQ(1, field->varint_size());
+  int number = field->number();
+
+  // Clear the set.
+  empty_message_.Clear();
+  EXPECT_EQ(0, unknown_fields_->field_count());
+
+  // If we add that field again we should get the same object.
+  ASSERT_EQ(field, unknown_fields_->AddField(number));
+
+  // But it should be cleared.
+  EXPECT_EQ(0, field->varint_size());
+}
+
+TEST_F(UnknownFieldSetTest, ParseKnownAndUnknown) {
+  // Test mixing known and unknown fields when parsing.
+
+  unittest::TestEmptyMessage source;
+  source.mutable_unknown_fields()->AddField(123456)->add_varint(654321);
+  string data;
+  ASSERT_TRUE(source.SerializeToString(&data));
+
+  unittest::TestAllTypes destination;
+  ASSERT_TRUE(destination.ParseFromString(all_fields_data_ + data));
+
+  TestUtil::ExpectAllFieldsSet(destination);
+  ASSERT_EQ(1, destination.unknown_fields().field_count());
+  ASSERT_EQ(1, destination.unknown_fields().field(0).varint_size());
+  EXPECT_EQ(654321, destination.unknown_fields().field(0).varint(0));
+}
+
+TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknown) {
+  // Test that fields of the wrong wire type are treated like unknown fields
+  // when parsing.
+
+  unittest::TestAllTypes all_types_message;
+  unittest::TestEmptyMessage empty_message;
+  string bizarro_data = GetBizarroData();
+  ASSERT_TRUE(all_types_message.ParseFromString(bizarro_data));
+  ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));
+
+  // All fields should have been interpreted as unknown, so the debug strings
+  // should be the same.
+  EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknownViaReflection) {
+  // Same as WrongTypeTreatedAsUnknown but via the reflection interface.
+
+  unittest::TestAllTypes all_types_message;
+  unittest::TestEmptyMessage empty_message;
+  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(empty_message.ParseFromString(bizarro_data));
+
+  EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, UnknownExtensions) {
+  // Make sure fields are properly parsed to the UnknownFieldSet even when
+  // they are declared as extension numbers.
+
+  unittest::TestEmptyMessageWithExtensions message;
+  ASSERT_TRUE(message.ParseFromString(all_fields_data_));
+
+  EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, UnknownExtensionsReflection) {
+  // Same as UnknownExtensions except parsing via reflection.
+
+  unittest::TestEmptyMessageWithExtensions message;
+  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()));
+
+  EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, WrongExtensionTypeTreatedAsUnknown) {
+  // Test that fields of the wrong wire type are treated like unknown fields
+  // when parsing extensions.
+
+  unittest::TestAllExtensions all_extensions_message;
+  unittest::TestEmptyMessage empty_message;
+  string bizarro_data = GetBizarroData();
+  ASSERT_TRUE(all_extensions_message.ParseFromString(bizarro_data));
+  ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));
+
+  // All fields should have been interpreted as unknown, so the debug strings
+  // should be the same.
+  EXPECT_EQ(empty_message.DebugString(), all_extensions_message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, UnknownEnumValue) {
+  using unittest::TestAllTypes;
+  using unittest::TestAllExtensions;
+  using unittest::TestEmptyMessage;
+
+  const FieldDescriptor* singular_field =
+    TestAllTypes::descriptor()->FindFieldByName("optional_nested_enum");
+  const FieldDescriptor* repeated_field =
+    TestAllTypes::descriptor()->FindFieldByName("repeated_nested_enum");
+  ASSERT_TRUE(singular_field != NULL);
+  ASSERT_TRUE(repeated_field != NULL);
+
+  string data;
+
+  {
+    TestEmptyMessage empty_message;
+    UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields();
+    UnknownField* singular_unknown_field =
+      unknown_fields->AddField(singular_field->number());
+    singular_unknown_field->add_varint(TestAllTypes::BAR);
+    singular_unknown_field->add_varint(5);  // not valid
+    UnknownField* repeated_unknown_field =
+      unknown_fields->AddField(repeated_field->number());
+    repeated_unknown_field->add_varint(TestAllTypes::FOO);
+    repeated_unknown_field->add_varint(4);  // not valid
+    repeated_unknown_field->add_varint(TestAllTypes::BAZ);
+    repeated_unknown_field->add_varint(6);  // not valid
+    empty_message.SerializeToString(&data);
+  }
+
+  {
+    TestAllTypes message;
+    ASSERT_TRUE(message.ParseFromString(data));
+    EXPECT_EQ(TestAllTypes::BAR, message.optional_nested_enum());
+    ASSERT_EQ(2, message.repeated_nested_enum_size());
+    EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(0));
+    EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(1));
+
+    const UnknownFieldSet& unknown_fields = message.unknown_fields();
+    ASSERT_EQ(2, unknown_fields.field_count());
+
+    const UnknownField& singular_unknown_field = unknown_fields.field(0);
+    ASSERT_EQ(singular_field->number(), singular_unknown_field.number());
+    ASSERT_EQ(1, singular_unknown_field.varint_size());
+    EXPECT_EQ(5, singular_unknown_field.varint(0));
+
+    const UnknownField& repeated_unknown_field = unknown_fields.field(1);
+    ASSERT_EQ(repeated_field->number(), repeated_unknown_field.number());
+    ASSERT_EQ(2, repeated_unknown_field.varint_size());
+    EXPECT_EQ(4, repeated_unknown_field.varint(0));
+    EXPECT_EQ(6, repeated_unknown_field.varint(1));
+  }
+
+  {
+    using unittest::optional_nested_enum_extension;
+    using unittest::repeated_nested_enum_extension;
+
+    TestAllExtensions message;
+    ASSERT_TRUE(message.ParseFromString(data));
+    EXPECT_EQ(TestAllTypes::BAR,
+              message.GetExtension(optional_nested_enum_extension));
+    ASSERT_EQ(2, message.ExtensionSize(repeated_nested_enum_extension));
+    EXPECT_EQ(TestAllTypes::FOO,
+              message.GetExtension(repeated_nested_enum_extension, 0));
+    EXPECT_EQ(TestAllTypes::BAZ,
+              message.GetExtension(repeated_nested_enum_extension, 1));
+
+    const UnknownFieldSet& unknown_fields = message.unknown_fields();
+    ASSERT_EQ(2, unknown_fields.field_count());
+
+    const UnknownField& singular_unknown_field = unknown_fields.field(0);
+    ASSERT_EQ(singular_field->number(), singular_unknown_field.number());
+    ASSERT_EQ(1, singular_unknown_field.varint_size());
+    EXPECT_EQ(5, singular_unknown_field.varint(0));
+
+    const UnknownField& repeated_unknown_field = unknown_fields.field(1);
+    ASSERT_EQ(repeated_field->number(), repeated_unknown_field.number());
+    ASSERT_EQ(2, repeated_unknown_field.varint_size());
+    EXPECT_EQ(4, repeated_unknown_field.varint(0));
+    EXPECT_EQ(6, repeated_unknown_field.varint(1));
+  }
+}
+
+}  // namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc
new file mode 100644
index 0000000..77e9c74
--- /dev/null
+++ b/src/google/protobuf/wire_format.cc
@@ -0,0 +1,801 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <stack>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/wire_format_inl.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/unknown_field_set.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+namespace {
+
+// This function turns out to be convenient when using some macros later.
+inline int GetEnumNumber(const EnumValueDescriptor* descriptor) {
+  return descriptor->number();
+}
+
+// These are the tags for the old MessageSet format, which was defined as:
+//   message MessageSet {
+//     repeated group Item = 1 {
+//       required int32 type_id = 2;
+//       required string message = 3;
+//     }
+//   }
+const int kMessageSetItemStartTag =
+  GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(1, WireFormat::WIRETYPE_START_GROUP);
+const int kMessageSetItemEndTag =
+  GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(1, WireFormat::WIRETYPE_END_GROUP);
+const int kMessageSetTypeIdTag =
+  GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(2, WireFormat::WIRETYPE_VARINT);
+const int kMessageSetMessageTag =
+  GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(3, WireFormat::WIRETYPE_LENGTH_DELIMITED);
+
+// Byte size of all tags of a MessageSet::Item combined.
+static const int kMessageSetItemTagsSize =
+  io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) +
+  io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) +
+  io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) +
+  io::CodedOutputStream::VarintSize32(kMessageSetMessageTag);
+
+}  // anonymous namespace
+
+const WireFormat::WireType
+WireFormat::kWireTypeForFieldType[FieldDescriptor::MAX_TYPE + 1] = {
+  static_cast<WireFormat::WireType>(-1),  // invalid
+  WIRETYPE_FIXED64,           // TYPE_DOUBLE
+  WIRETYPE_FIXED32,           // TYPE_FLOAT
+  WIRETYPE_VARINT,            // TYPE_INT64
+  WIRETYPE_VARINT,            // TYPE_UINT64
+  WIRETYPE_VARINT,            // TYPE_INT32
+  WIRETYPE_FIXED64,           // TYPE_FIXED64
+  WIRETYPE_FIXED32,           // TYPE_FIXED32
+  WIRETYPE_VARINT,            // TYPE_BOOL
+  WIRETYPE_LENGTH_DELIMITED,  // TYPE_STRING
+  WIRETYPE_START_GROUP,       // TYPE_GROUP
+  WIRETYPE_LENGTH_DELIMITED,  // TYPE_MESSAGE
+  WIRETYPE_LENGTH_DELIMITED,  // TYPE_BYTES
+  WIRETYPE_VARINT,            // TYPE_UINT32
+  WIRETYPE_VARINT,            // TYPE_ENUM
+  WIRETYPE_FIXED32,           // TYPE_SFIXED32
+  WIRETYPE_FIXED64,           // TYPE_SFIXED64
+  WIRETYPE_VARINT,            // TYPE_SINT32
+  WIRETYPE_VARINT,            // TYPE_SINT64
+};
+
+// ===================================================================
+
+bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag,
+                           UnknownFieldSet* unknown_fields) {
+  UnknownField* field = (unknown_fields == NULL) ? NULL :
+    unknown_fields->AddField(GetTagFieldNumber(tag));
+
+  switch (GetTagWireType(tag)) {
+    case WIRETYPE_VARINT: {
+      uint64 value;
+      if (!input->ReadVarint64(&value)) return false;
+      if (field != NULL) field->add_varint(value);
+      return true;
+    }
+    case WIRETYPE_FIXED64: {
+      uint64 value;
+      if (!input->ReadLittleEndian64(&value)) return false;
+      if (field != NULL) field->add_fixed64(value);
+      return true;
+    }
+    case WIRETYPE_LENGTH_DELIMITED: {
+      uint32 length;
+      if (!input->ReadVarint32(&length)) return false;
+      if (field == NULL) {
+        if (!input->Skip(length)) return false;
+      } else {
+        input->ReadString(field->add_length_delimited(), length);
+      }
+      return true;
+    }
+    case WIRETYPE_START_GROUP: {
+      if (!input->IncrementRecursionDepth()) return false;
+      if (!SkipMessage(input, (field == NULL) ? NULL : field->add_group())) {
+        return false;
+      }
+      input->DecrementRecursionDepth();
+      // Check that the ending tag matched the starting tag.
+      if (!input->LastTagWas(
+          MakeTag(GetTagFieldNumber(tag), WIRETYPE_END_GROUP))) {
+        return false;
+      }
+      return true;
+    }
+    case WIRETYPE_END_GROUP: {
+      return false;
+    }
+    case WIRETYPE_FIXED32: {
+      uint32 value;
+      if (!input->ReadLittleEndian32(&value)) return false;
+      if (field != NULL) field->add_fixed32(value);
+      return true;
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+bool WireFormat::SkipMessage(io::CodedInputStream* input,
+                             UnknownFieldSet* unknown_fields) {
+  while(true) {
+    uint32 tag = input->ReadTag();
+    if (tag == 0) {
+      // End of input.  This is a valid place to end, so return true.
+      return true;
+    }
+
+    WireType wire_type = GetTagWireType(tag);
+
+    if (wire_type == WIRETYPE_END_GROUP) {
+      // Must be the end of the message.
+      return true;
+    }
+
+    if (!SkipField(input, tag, unknown_fields)) return false;
+  }
+}
+
+bool WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
+                                        io::CodedOutputStream* output) {
+  for (int i = 0; i < unknown_fields.field_count(); i++) {
+    const UnknownField& field = unknown_fields.field(i);
+
+#define DO(EXPRESSION) if (!(EXPRESSION)) return false
+    for (int j = 0; j < field.varint_size(); j++) {
+      DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_VARINT)));
+      DO(output->WriteVarint64(field.varint(j)));
+    }
+    for (int j = 0; j < field.fixed32_size(); j++) {
+      DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_FIXED32)));
+      DO(output->WriteLittleEndian32(field.fixed32(j)));
+    }
+    for (int j = 0; j < field.fixed64_size(); j++) {
+      DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_FIXED64)));
+      DO(output->WriteLittleEndian64(field.fixed64(j)));
+    }
+    for (int j = 0; j < field.length_delimited_size(); j++) {
+      DO(output->WriteVarint32(
+        MakeTag(field.number(), WIRETYPE_LENGTH_DELIMITED)));
+      DO(output->WriteVarint32(field.length_delimited(j).size()));
+      DO(output->WriteString(field.length_delimited(j)));
+    }
+    for (int j = 0; j < field.group_size(); j++) {
+      DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_START_GROUP)));
+      DO(SerializeUnknownFields(field.group(j), output));
+      DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_END_GROUP)));
+    }
+#undef DO
+  }
+
+  return true;
+}
+
+bool WireFormat::SerializeUnknownMessageSetItems(
+    const UnknownFieldSet& unknown_fields,
+    io::CodedOutputStream* output) {
+  for (int i = 0; i < unknown_fields.field_count(); i++) {
+    const UnknownField& field = unknown_fields.field(i);
+
+#define DO(EXPRESSION) if (!(EXPRESSION)) return false
+    // The only unknown fields that are allowed to exist in a MessageSet are
+    // messages, which are length-delimited.
+    for (int j = 0; j < field.length_delimited_size(); j++) {
+      const string& data = field.length_delimited(j);
+
+      // Start group.
+      DO(output->WriteVarint32(kMessageSetItemStartTag));
+
+      // Write type ID.
+      DO(output->WriteVarint32(kMessageSetTypeIdTag));
+      DO(output->WriteVarint32(field.number()));
+
+      // Write message.
+      DO(output->WriteVarint32(kMessageSetMessageTag));
+      DO(output->WriteVarint32(data.size()));
+      DO(output->WriteString(data));
+
+      // End group.
+      DO(output->WriteVarint32(kMessageSetItemEndTag));
+    }
+#undef DO
+  }
+
+  return true;
+}
+
+int WireFormat::ComputeUnknownFieldsSize(
+    const UnknownFieldSet& unknown_fields) {
+  int size = 0;
+  for (int i = 0; i < unknown_fields.field_count(); i++) {
+    const UnknownField& field = unknown_fields.field(i);
+
+    for (int j = 0; j < field.varint_size(); j++) {
+      size += io::CodedOutputStream::VarintSize32(
+        MakeTag(field.number(), WIRETYPE_VARINT));
+      size += io::CodedOutputStream::VarintSize64(field.varint(j));
+    }
+    for (int j = 0; j < field.fixed32_size(); j++) {
+      size += io::CodedOutputStream::VarintSize32(
+        MakeTag(field.number(), WIRETYPE_FIXED32));
+      size += sizeof(int32);
+    }
+    for (int j = 0; j < field.fixed64_size(); j++) {
+      size += io::CodedOutputStream::VarintSize32(
+        MakeTag(field.number(), WIRETYPE_FIXED64));
+      size += sizeof(int64);
+    }
+    for (int j = 0; j < field.length_delimited_size(); j++) {
+      size += io::CodedOutputStream::VarintSize32(
+        MakeTag(field.number(), WIRETYPE_LENGTH_DELIMITED));
+      size += io::CodedOutputStream::VarintSize32(
+        field.length_delimited(j).size());
+      size += field.length_delimited(j).size();
+    }
+    for (int j = 0; j < field.group_size(); j++) {
+      size += io::CodedOutputStream::VarintSize32(
+        MakeTag(field.number(), WIRETYPE_START_GROUP));
+      size += ComputeUnknownFieldsSize(field.group(j));
+      size += io::CodedOutputStream::VarintSize32(
+        MakeTag(field.number(), WIRETYPE_END_GROUP));
+    }
+  }
+
+  return size;
+}
+
+int WireFormat::ComputeUnknownMessageSetItemsSize(
+    const UnknownFieldSet& unknown_fields) {
+  int size = 0;
+  for (int i = 0; i < unknown_fields.field_count(); i++) {
+    const UnknownField& field = unknown_fields.field(i);
+
+    // The only unknown fields that are allowed to exist in a MessageSet are
+    // messages, which are length-delimited.
+    for (int j = 0; j < field.length_delimited_size(); j++) {
+      size += kMessageSetItemTagsSize;
+      size += io::CodedOutputStream::VarintSize32(field.number());
+      size += io::CodedOutputStream::VarintSize32(
+        field.length_delimited(j).size());
+      size += field.length_delimited(j).size();
+    }
+  }
+
+  return size;
+}
+
+// ===================================================================
+
+bool WireFormat::ParseAndMergePartial(const Descriptor* descriptor,
+                                      io::CodedInputStream* input,
+                                      Message::Reflection* message_reflection) {
+  while(true) {
+    uint32 tag = input->ReadTag();
+    if (tag == 0) {
+      // End of input.  This is a valid place to end, so return true.
+      return true;
+    }
+
+    if (GetTagWireType(tag) == WIRETYPE_END_GROUP) {
+      // Must be the end of the message.
+      return true;
+    }
+
+    const FieldDescriptor* field = NULL;
+
+    if (descriptor != NULL) {
+      int field_number = GetTagFieldNumber(tag);
+      field = descriptor->FindFieldByNumber(field_number);
+
+      // If that failed, check if the field is an extension.
+      if (field == NULL && descriptor->IsExtensionNumber(field_number)) {
+        field = message_reflection->FindKnownExtensionByNumber(field_number);
+      }
+
+      // If that failed, but we're a MessageSet, and this is the tag for a
+      // MessageSet item, then parse that.
+      if (field == NULL &&
+          descriptor->options().message_set_wire_format() &&
+          tag == kMessageSetItemStartTag) {
+        if (!ParseAndMergeMessageSetItem(input, message_reflection)) {
+          return false;
+        }
+        continue;  // Skip ParseAndMergeField(); already taken care of.
+      }
+    }
+
+    if (!ParseAndMergeField(tag, field, message_reflection, input)) {
+      return false;
+    }
+  }
+}
+
+bool WireFormat::ParseAndMergeField(
+    uint32 tag,
+    const FieldDescriptor* field,        // May be NULL for unknown
+    Message::Reflection* message_reflection,
+    io::CodedInputStream* input) {
+  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());
+  }
+
+  switch (field->type()) {
+#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD)         \
+    case FieldDescriptor::TYPE_##TYPE: {                                \
+      CPPTYPE value;                                                    \
+      if (!Read##TYPE_METHOD(input, &value)) return false;              \
+      if (field->is_repeated()) {                                       \
+        message_reflection->Add##CPPTYPE_METHOD(field, value);          \
+      } else {                                                          \
+        message_reflection->Set##CPPTYPE_METHOD(field, value);          \
+      }                                                                 \
+      break;                                                            \
+    }
+
+    HANDLE_TYPE( INT32,  Int32,  int32,  Int32)
+    HANDLE_TYPE( INT64,  Int64,  int64,  Int64)
+    HANDLE_TYPE(SINT32, SInt32,  int32,  Int32)
+    HANDLE_TYPE(SINT64, SInt64,  int64,  Int64)
+    HANDLE_TYPE(UINT32, UInt32, uint32, UInt32)
+    HANDLE_TYPE(UINT64, UInt64, uint64, UInt64)
+
+    HANDLE_TYPE( FIXED32,  Fixed32, uint32, UInt32)
+    HANDLE_TYPE( FIXED64,  Fixed64, uint64, UInt64)
+    HANDLE_TYPE(SFIXED32, SFixed32,  int32,  Int32)
+    HANDLE_TYPE(SFIXED64, SFixed64,  int64,  Int64)
+
+    HANDLE_TYPE(FLOAT , Float , float , Float )
+    HANDLE_TYPE(DOUBLE, Double, double, Double)
+
+    HANDLE_TYPE(BOOL, Bool, bool, Bool)
+
+    HANDLE_TYPE(STRING, String, string, String)
+    HANDLE_TYPE(BYTES, Bytes, string, String)
+
+#undef HANDLE_TYPE
+
+    case FieldDescriptor::TYPE_ENUM: {
+      int value;
+      if (!ReadEnum(input, &value)) return false;
+      const EnumValueDescriptor* enum_value =
+        field->enum_type()->FindValueByNumber(value);
+      if (enum_value != NULL) {
+        if (field->is_repeated()) {
+          message_reflection->AddEnum(field, enum_value);
+        } else {
+          message_reflection->SetEnum(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()
+                          ->AddField(GetTagFieldNumber(tag))
+                          ->add_varint(sign_extended_value);
+      }
+      break;
+    }
+
+
+    case FieldDescriptor::TYPE_GROUP: {
+      Message* sub_message;
+      if (field->is_repeated()) {
+        sub_message = message_reflection->AddMessage(field);
+      } else {
+        sub_message = message_reflection->MutableMessage(field);
+      }
+
+      if (!ReadGroup(GetTagFieldNumber(tag), input, sub_message)) return false;
+      break;
+    }
+
+    case FieldDescriptor::TYPE_MESSAGE: {
+      Message* sub_message;
+      if (field->is_repeated()) {
+        sub_message = message_reflection->AddMessage(field);
+      } else {
+        sub_message = message_reflection->MutableMessage(field);
+      }
+
+      if (!ReadMessage(input, sub_message)) return false;
+      break;
+    }
+  }
+
+  return true;
+}
+
+bool WireFormat::ParseAndMergeMessageSetItem(
+    io::CodedInputStream* input,
+    Message::Reflection* message_reflection) {
+  // This method parses a group which should contain two fields:
+  //   required int32 type_id = 2;
+  //   required data message = 3;
+
+  // Once we see a type_id, we'll construct a fake tag for this extension
+  // which is the tag it would have had under the proto2 extensions wire
+  // format.
+  uint32 fake_tag = 0;
+
+  // Once we see a type_id, we'll look up the FieldDescriptor for the
+  // extension.
+  const FieldDescriptor* field = NULL;
+
+  // If we see message data before the type_id, we'll append it to this so
+  // we can parse it later.  This will probably never happen in practice,
+  // as no MessageSet encoder I know of writes the message before the type ID.
+  // But, it's technically valid so we should allow it.
+  // TODO(kenton):  Use a Cord instead?  Do I care?
+  string message_data;
+
+  while (true) {
+    uint32 tag = input->ReadTag();
+    if (tag == 0) return false;
+
+    switch (tag) {
+      case kMessageSetTypeIdTag: {
+        uint32 type_id;
+        if (!input->ReadVarint32(&type_id)) return false;
+        fake_tag = MakeTag(type_id, WIRETYPE_LENGTH_DELIMITED);
+        field = message_reflection->FindKnownExtensionByNumber(type_id);
+
+        if (!message_data.empty()) {
+          // We saw some message data before the type_id.  Have to parse it
+          // now.
+          io::ArrayInputStream raw_input(message_data.data(),
+                                         message_data.size());
+          io::CodedInputStream sub_input(&raw_input);
+          if (!ParseAndMergeField(fake_tag, field, message_reflection,
+                                  &sub_input)) {
+            return false;
+          }
+          message_data.clear();
+        }
+
+        break;
+      }
+
+      case kMessageSetMessageTag: {
+        if (fake_tag == 0) {
+          // We haven't seen a type_id yet.  Append this data to message_data.
+          string temp;
+          uint32 length;
+          if (!input->ReadVarint32(&length)) return false;
+          if (!input->ReadString(&temp, length)) return false;
+          message_data.append(temp);
+        } else {
+          // Already saw type_id, so we can parse this directly.
+          if (!ParseAndMergeField(fake_tag, field, message_reflection, input)) {
+            return false;
+          }
+        }
+
+        break;
+      }
+
+      case kMessageSetItemEndTag: {
+        return true;
+      }
+
+      default: {
+        if (!SkipField(input, tag, NULL)) return false;
+      }
+    }
+  }
+}
+
+// ===================================================================
+
+bool WireFormat::SerializeWithCachedSizes(
+    const Descriptor* descriptor,
+    const Message::Reflection* message_reflection,
+    int size, io::CodedOutputStream* output) {
+  int expected_endpoint = output->ByteCount() + size;
+
+  vector<const FieldDescriptor*> fields;
+  message_reflection->ListFields(&fields);
+  for (int i = 0; i < fields.size(); i++) {
+    if (!SerializeFieldWithCachedSizes(fields[i], message_reflection, output)) {
+      return false;
+    }
+  }
+
+  if (descriptor->options().message_set_wire_format()) {
+    if (!SerializeUnknownMessageSetItems(
+           message_reflection->GetUnknownFields(), output)) {
+      return false;
+    }
+  } else {
+    if (!SerializeUnknownFields(
+           message_reflection->GetUnknownFields(), output)) {
+      return false;
+    }
+  }
+
+  GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint)
+    << ": Protocol message serialized to a size different from what was "
+       "originally expected.  Perhaps it was modified by another thread "
+       "during serialization?";
+
+  return true;
+}
+
+bool WireFormat::SerializeFieldWithCachedSizes(
+    const FieldDescriptor* field,
+    const Message::Reflection* message_reflection,
+    io::CodedOutputStream* output) {
+  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);
+  }
+
+  int count = 0;
+
+  if (field->is_repeated()) {
+    count = message_reflection->FieldSize(field);
+  } else if (message_reflection->HasField(field)) {
+    count = 1;
+  }
+
+  for (int j = 0; j < count; j++) {
+    switch (field->type()) {
+#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                       \
+      case FieldDescriptor::TYPE_##TYPE:                                     \
+        if (!Write##TYPE_METHOD(                                             \
+              field->number(),                                               \
+              field->is_repeated() ?                                         \
+                message_reflection->GetRepeated##CPPTYPE_METHOD(field, j) :  \
+                message_reflection->Get##CPPTYPE_METHOD(field),              \
+              output)) {                                                     \
+          return false;                                                      \
+        }                                                                    \
+        break;
+
+      HANDLE_TYPE( INT32,  Int32,  Int32)
+      HANDLE_TYPE( INT64,  Int64,  Int64)
+      HANDLE_TYPE(SINT32, SInt32,  Int32)
+      HANDLE_TYPE(SINT64, SInt64,  Int64)
+      HANDLE_TYPE(UINT32, UInt32, UInt32)
+      HANDLE_TYPE(UINT64, UInt64, UInt64)
+
+      HANDLE_TYPE( FIXED32,  Fixed32, UInt32)
+      HANDLE_TYPE( FIXED64,  Fixed64, UInt64)
+      HANDLE_TYPE(SFIXED32, SFixed32,  Int32)
+      HANDLE_TYPE(SFIXED64, SFixed64,  Int64)
+
+      HANDLE_TYPE(FLOAT , Float , Float )
+      HANDLE_TYPE(DOUBLE, Double, Double)
+
+      HANDLE_TYPE(BOOL, Bool, Bool)
+
+      HANDLE_TYPE(GROUP  , Group  , Message)
+      HANDLE_TYPE(MESSAGE, Message, Message)
+#undef HANDLE_TYPE
+
+      case FieldDescriptor::TYPE_ENUM: {
+        const EnumValueDescriptor* value = field->is_repeated() ?
+          message_reflection->GetRepeatedEnum(field, j) :
+          message_reflection->GetEnum(field);
+        if (!WriteEnum(field->number(), value->number(), output)) return false;
+        break;
+      }
+
+      // Handle strings separately so that we can get string references
+      // instead of copying.
+      case FieldDescriptor::TYPE_STRING:
+      case FieldDescriptor::TYPE_BYTES: {
+          string scratch;
+          const string& value = field->is_repeated() ?
+            message_reflection->GetRepeatedStringReference(field, j, &scratch) :
+            message_reflection->GetStringReference(field, &scratch);
+          if (!WriteString(field->number(), value, output)) return false;
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+bool WireFormat::SerializeMessageSetItemWithCachedSizes(
+    const FieldDescriptor* field,
+    const Message::Reflection* message_reflection,
+    io::CodedOutputStream* output) {
+  // Start group.
+  if (!output->WriteVarint32(kMessageSetItemStartTag)) return false;
+
+  // Write type ID.
+  if (!output->WriteVarint32(kMessageSetTypeIdTag)) return false;
+  if (!output->WriteVarint32(field->number())) return false;
+
+  // Write message.
+  if (!output->WriteVarint32(kMessageSetMessageTag)) return false;
+
+  const Message& sub_message = message_reflection->GetMessage(field);
+  if (!output->WriteVarint32(sub_message.GetCachedSize())) return false;
+  if (!sub_message.SerializeWithCachedSizes(output)) return false;
+
+  // End group.
+  if (!output->WriteVarint32(kMessageSetItemEndTag)) return false;
+
+  return true;
+}
+
+// ===================================================================
+
+int WireFormat::ByteSize(
+    const Descriptor* descriptor,
+    const Message::Reflection* message_reflection) {
+  int our_size = 0;
+
+  vector<const FieldDescriptor*> fields;
+  message_reflection->ListFields(&fields);
+  for (int i = 0; i < fields.size(); i++) {
+    our_size += FieldByteSize(fields[i], message_reflection);
+  }
+
+  if (descriptor->options().message_set_wire_format()) {
+    our_size += ComputeUnknownMessageSetItemsSize(
+      message_reflection->GetUnknownFields());
+  } else {
+    our_size += ComputeUnknownFieldsSize(
+      message_reflection->GetUnknownFields());
+  }
+
+  return our_size;
+}
+
+int WireFormat::FieldByteSize(
+    const FieldDescriptor* field,
+    const Message::Reflection* message_reflection) {
+  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);
+  }
+
+  int our_size = 0;
+
+  int count = 0;
+
+  if (field->is_repeated()) {
+    count = message_reflection->FieldSize(field);
+  } else if (message_reflection->HasField(field)) {
+    count = 1;
+  }
+
+  our_size += count * TagSize(field->number(), field->type());
+
+  switch (field->type()) {
+#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                     \
+    case FieldDescriptor::TYPE_##TYPE:                                     \
+      if (field->is_repeated()) {                                          \
+        for (int j = 0; j < count; j++) {                                  \
+          our_size += TYPE_METHOD##Size(                                   \
+            message_reflection->GetRepeated##CPPTYPE_METHOD(field, j));    \
+        }                                                                  \
+      } else {                                                             \
+        our_size += TYPE_METHOD##Size(                                     \
+          message_reflection->Get##CPPTYPE_METHOD(field));                 \
+      }                                                                    \
+      break;
+
+#define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD)                               \
+    case FieldDescriptor::TYPE_##TYPE:                                     \
+      our_size += count * k##TYPE_METHOD##Size;                            \
+      break;
+
+    HANDLE_TYPE( INT32,  Int32,  Int32)
+    HANDLE_TYPE( INT64,  Int64,  Int64)
+    HANDLE_TYPE(SINT32, SInt32,  Int32)
+    HANDLE_TYPE(SINT64, SInt64,  Int64)
+    HANDLE_TYPE(UINT32, UInt32, UInt32)
+    HANDLE_TYPE(UINT64, UInt64, UInt64)
+
+    HANDLE_FIXED_TYPE( FIXED32,  Fixed32)
+    HANDLE_FIXED_TYPE( FIXED64,  Fixed64)
+    HANDLE_FIXED_TYPE(SFIXED32, SFixed32)
+    HANDLE_FIXED_TYPE(SFIXED64, SFixed64)
+
+    HANDLE_FIXED_TYPE(FLOAT , Float )
+    HANDLE_FIXED_TYPE(DOUBLE, Double)
+
+    HANDLE_FIXED_TYPE(BOOL, Bool)
+
+    HANDLE_TYPE(GROUP  , Group  , Message)
+    HANDLE_TYPE(MESSAGE, Message, Message)
+#undef HANDLE_TYPE
+#undef HANDLE_FIXED_TYPE
+
+    case FieldDescriptor::TYPE_ENUM: {
+      if (field->is_repeated()) {
+        for (int j = 0; j < count; j++) {
+          our_size += EnumSize(
+            message_reflection->GetRepeatedEnum(field, j)->number());
+        }
+      } else {
+        our_size += EnumSize(
+          message_reflection->GetEnum(field)->number());
+      }
+      break;
+    }
+
+    // Handle strings separately so that we can get string references
+    // instead of copying.
+    case FieldDescriptor::TYPE_STRING:
+    case FieldDescriptor::TYPE_BYTES: {
+        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);
+          our_size += StringSize(value);
+        }
+      break;
+    }
+  }
+
+  return our_size;
+}
+
+int WireFormat::MessageSetItemByteSize(
+    const FieldDescriptor* field,
+    const Message::Reflection* message_reflection) {
+  int our_size = kMessageSetItemTagsSize;
+
+  // type_id
+  our_size += io::CodedOutputStream::VarintSize32(field->number());
+
+  // message
+  const Message& sub_message = message_reflection->GetMessage(field);
+  int message_size = sub_message.ByteSize();
+
+  our_size += io::CodedOutputStream::VarintSize32(message_size);
+  our_size += message_size;
+
+  return our_size;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h
new file mode 100644
index 0000000..d59f3fc
--- /dev/null
+++ b/src/google/protobuf/wire_format.h
@@ -0,0 +1,446 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//         atenasio@google.com (Chris Atenasio) (ZigZag transform)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_H__
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__
+
+#include <string>
+#include <google/protobuf/message.h>  // Message::Reflection
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+
+namespace protobuf {
+  namespace io {
+    class CodedInputStream;      // coded_stream.h
+    class CodedOutputStream;     // coded_stream.h
+  }
+  class UnknownFieldSet;       // unknown_field_set.h
+}
+
+namespace protobuf {
+namespace internal {
+
+// This class is for internal use by the protocol buffer library and by
+// protocol-complier-generated message classes.  It must not be called
+// directly by clients.
+//
+// This class contains helpers for implementing the binary protocol buffer
+// wire format.  These helpers are called primarily by generated code.  The
+// class also contains reflection-based implementations of the wire format.
+//
+// This class is really a namespace that contains only static methods.
+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
+  // 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
+  // generates when told to optimize for speed.
+
+  // Read a message in protocol buffer wire format.
+  //
+  // This procedure reads either to the end of the input stream or through
+  // a WIRETYPE_END_GROUP tag ending the message, whichever comes first.
+  // It returns false if the input is invalid.
+  //
+  // 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);
+
+  // Serialize a message in protocol buffer wire format.
+  //
+  // Any embedded messages within the message must have their correct sizes
+  // cached.  However, the top-level message need not; its size is passed as
+  // a parameter to this procedure.
+  //
+  // These return false iff the underlying stream returns a write error.
+  static bool SerializeWithCachedSizes(
+      const Descriptor* descriptor,
+      const Message::Reflection* message_reflection,
+      int size, io::CodedOutputStream* output);
+
+  // Implements Message::ByteSize() via reflection.  WARNING:  The result
+  // of this method is *not* cached anywhere.  However, all embedded messages
+  // 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);
+
+  // -----------------------------------------------------------------
+  // Helpers for dealing with unknown fields
+
+  // Skips a field value of the given WireType.  The input should start
+  // positioned immediately after the tag.  If unknown_fields is non-NULL,
+  // the contents of the field will be added to it.
+  static bool SkipField(io::CodedInputStream* input, uint32 tag,
+                        UnknownFieldSet* unknown_fields);
+
+  // Reads and ignores a message from the input.  If unknown_fields is non-NULL,
+  // the contents will be added to it.
+  static bool SkipMessage(io::CodedInputStream* input,
+                          UnknownFieldSet* unknown_fields);
+
+  // Write the contents of an UnknownFieldSet to the output.
+  static bool SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
+                                     io::CodedOutputStream* output);
+
+  // Same thing except for messages that have the message_set_wire_format
+  // option.
+  static bool SerializeUnknownMessageSetItems(
+      const UnknownFieldSet& unknown_fields,
+      io::CodedOutputStream* output);
+
+  // Compute the size of the UnknownFieldSet on the wire.
+  static int ComputeUnknownFieldsSize(const UnknownFieldSet& unknown_fields);
+
+  // Same thing except for messages that have the message_set_wire_format
+  // option.
+  static int ComputeUnknownMessageSetItemsSize(
+      const UnknownFieldSet& unknown_fields);
+
+  // -----------------------------------------------------------------
+  // Helper constants and functions related to the format.  These are
+  // mostly meant for internal and generated code to use.
+
+  // The wire format is composed of a sequence of tag/value pairs, each
+  // of which contains the value of one field (or one element of a repeated
+  // field).  Each tag is encoded as a varint.  The lower bits of the tag
+  // identify its wire type, which specifies the format of the data to follow.
+  // The rest of the bits contain the field number.  Each type of field (as
+  // declared by FieldDescriptor::Type, in descriptor.h) maps to one of
+  // these wire types.  Immediately following each tag is the field's value,
+  // encoded in the format specified by the wire type.  Because the tag
+  // identifies the encoding of this data, it is possible to skip
+  // unrecognized fields for forwards compatibility.
+
+  enum WireType {
+    WIRETYPE_VARINT           = 0,
+    WIRETYPE_FIXED64          = 1,
+    WIRETYPE_LENGTH_DELIMITED = 2,
+    WIRETYPE_START_GROUP      = 3,
+    WIRETYPE_END_GROUP        = 4,
+    WIRETYPE_FIXED32          = 5,
+  };
+
+  static inline WireType WireTypeForFieldType(FieldDescriptor::Type type) {
+    return kWireTypeForFieldType[type];
+  }
+
+  // Number of bits in a tag which identify the wire type.
+  static const int kTagTypeBits = 3;
+  // Mask for those bits.
+  static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1;
+
+  // Helper functions for encoding and decoding tags.  (Inlined below.)
+  static uint32 MakeTag(const FieldDescriptor* field);
+  static uint32 MakeTag(int field_number, WireType type);
+  static WireType GetTagWireType(uint32 tag);
+  static int GetTagFieldNumber(uint32 tag);
+
+  // Helper functions for converting between floats/doubles and IEEE-754
+  // uint32s/uint64s so that they can be written.  (Assumes your platform
+  // uses IEEE-754 floats.)
+  static uint32 EncodeFloat(float value);
+  static float DecodeFloat(uint32 value);
+  static uint64 EncodeDouble(double value);
+  static double DecodeDouble(uint64 value);
+
+  // Helper functions for mapping signed integers to unsigned integers in
+  // such a way that numbers with small magnitudes will encode to smaller
+  // varints.  If you simply static_cast a negative number to an unsigned
+  // number and varint-encode it, it will always take 10 bytes, defeating
+  // the purpose of varint.  So, for the "sint32" and "sint64" field types,
+  // we ZigZag-encode the values.
+  static uint32 ZigZagEncode32(int32 n);
+  static int32  ZigZagDecode32(uint32 n);
+  static uint64 ZigZagEncode64(int64 n);
+  static int64  ZigZagDecode64(uint64 n);
+
+  // Parse a single field.  The input should start out positioned immidately
+  // after the tag.
+  static bool ParseAndMergeField(
+      uint32 tag,
+      const FieldDescriptor* field,        // May be NULL for unknown
+      Message::Reflection* message_reflection,
+      io::CodedInputStream* input);
+
+  // Serialize a single field.
+  static bool SerializeFieldWithCachedSizes(
+      const FieldDescriptor* field,        // Cannot be NULL
+      const Message::Reflection* message_reflection,
+      io::CodedOutputStream* output);
+
+  // Compute size of a single field.  If the field is a message type, this
+  // will call ByteSize() for the embedded message, insuring that it caches
+  // its size.
+  static int FieldByteSize(
+      const FieldDescriptor* field,        // Cannot be NULL
+      const Message::Reflection* message_reflection);
+
+  // =================================================================
+  // Methods for reading/writing individual field.  The implementations
+  // of these methods are defined in wire_format_inl.h; you must #include
+  // that file to use these.
+
+// Avoid ugly line wrapping
+#define input  io::CodedInputStream*  input
+#define output io::CodedOutputStream* output
+#define field_number int field_number
+#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+
+  // Read fields, not including tags.  The assumption is that you already
+  // read the tag to determine what field to read.
+  static inline bool ReadInt32   (input,  int32* value);
+  static inline bool ReadInt64   (input,  int64* value);
+  static inline bool ReadUInt32  (input, uint32* value);
+  static inline bool ReadUInt64  (input, uint64* value);
+  static inline bool ReadSInt32  (input,  int32* value);
+  static inline bool ReadSInt64  (input,  int64* value);
+  static inline bool ReadFixed32 (input, uint32* value);
+  static inline bool ReadFixed64 (input, uint64* value);
+  static inline bool ReadSFixed32(input,  int32* value);
+  static inline bool ReadSFixed64(input,  int64* value);
+  static inline bool ReadFloat   (input,  float* value);
+  static inline bool ReadDouble  (input, double* value);
+  static inline bool ReadBool    (input,   bool* value);
+  static inline bool ReadEnum    (input,    int* value);
+
+  static inline bool ReadString(input, string* value);
+  static inline bool ReadBytes (input, string* value);
+
+  static inline bool ReadGroup  (field_number, input, Message* value);
+  static inline bool ReadMessage(input, Message* value);
+
+  // Like above, but de-virtualize the call to MergePartialFromCodedStream().
+  // The pointer must point at an instance of MessageType, *not* a subclass (or
+  // the subclass must not override MergePartialFromCodedStream()).
+  template<typename MessageType>
+  static inline bool ReadGroupNoVirtual(field_number, input,
+                                        MessageType* value);
+  template<typename MessageType>
+  static inline bool ReadMessageNoVirtual(input, MessageType* value);
+
+  // Write a tag.  The Write*() functions automatically include the tag, so
+  // normally there's no need to call this.
+  static inline bool WriteTag(field_number, WireType type, output) INL;
+
+  // Write fields, including tags.
+  static inline bool WriteInt32   (field_number,  int32 value, output) INL;
+  static inline bool WriteInt64   (field_number,  int64 value, output) INL;
+  static inline bool WriteUInt32  (field_number, uint32 value, output) INL;
+  static inline bool WriteUInt64  (field_number, uint64 value, output) INL;
+  static inline bool WriteSInt32  (field_number,  int32 value, output) INL;
+  static inline bool WriteSInt64  (field_number,  int64 value, output) INL;
+  static inline bool WriteFixed32 (field_number, uint32 value, output) INL;
+  static inline bool WriteFixed64 (field_number, uint64 value, output) INL;
+  static inline bool WriteSFixed32(field_number,  int32 value, output) INL;
+  static inline bool WriteSFixed64(field_number,  int64 value, output) INL;
+  static inline bool WriteFloat   (field_number,  float value, output) INL;
+  static inline bool WriteDouble  (field_number, double value, output) INL;
+  static inline bool WriteBool    (field_number,   bool value, output) INL;
+  static inline bool WriteEnum    (field_number,    int value, output) INL;
+
+  static inline bool WriteString(field_number, const string& value, output) INL;
+  static inline bool WriteBytes (field_number, const string& value, output) INL;
+
+  static inline bool WriteGroup(field_number, const Message& value, output) INL;
+  static inline bool WriteMessage(
+    field_number, const Message& value, output) INL;
+
+  // Like above, but de-virtualize the call to SerializeWithCachedSizes().  The
+  // pointer must point at an instance of MessageType, *not* a subclass (or
+  // the subclass must not override SerializeWithCachedSizes()).
+  template<typename MessageType>
+  static inline bool WriteGroupNoVirtual(
+    field_number, const MessageType& value, output) INL;
+  template<typename MessageType>
+  static inline bool WriteMessageNoVirtual(
+    field_number, const MessageType& value, output) INL;
+
+  // Compute the byte size of a tag.  For groups, this includes both the start
+  // and end tags.
+  static inline int TagSize(field_number, FieldDescriptor::Type type);
+
+  // Compute the byte size of a field.  The XxSize() functions do NOT include
+  // the tag, so you must also call TagSize().  (This is because, for repeated
+  // fields, you should only call TagSize() once and multiply it by the element
+  // count, but you may have to call XxSize() for each individual element.)
+  static inline int Int32Size   ( int32 value);
+  static inline int Int64Size   ( int64 value);
+  static inline int UInt32Size  (uint32 value);
+  static inline int UInt64Size  (uint64 value);
+  static inline int SInt32Size  ( int32 value);
+  static inline int SInt64Size  ( int64 value);
+  static inline int EnumSize    (   int value);
+
+  // These types always have the same size.
+  static const int kFixed32Size  = 4;
+  static const int kFixed64Size  = 8;
+  static const int kSFixed32Size = 4;
+  static const int kSFixed64Size = 8;
+  static const int kFloatSize    = 4;
+  static const int kDoubleSize   = 8;
+  static const int kBoolSize     = 1;
+
+  static inline int StringSize(const string& value);
+  static inline int BytesSize (const string& value);
+
+  static inline int GroupSize  (const Message& value);
+  static inline int MessageSize(const Message& value);
+
+  // Like above, but de-virtualize the call to ByteSize().  The
+  // pointer must point at an instance of MessageType, *not* a subclass (or
+  // the subclass must not override ByteSize()).
+  template<typename MessageType>
+  static inline int GroupSizeNoVirtual  (const MessageType& value);
+  template<typename MessageType>
+  static inline int MessageSizeNoVirtual(const MessageType& value);
+
+#undef input
+#undef output
+#undef field_number
+#undef INL
+
+ private:
+  static const WireType kWireTypeForFieldType[];
+
+  // Parse/serialize a MessageSet::Item group.  Used with messages that use
+  // opion message_set_wire_format = true.
+  static bool ParseAndMergeMessageSetItem(
+      io::CodedInputStream* input,
+      Message::Reflection* message_reflection);
+  static bool SerializeMessageSetItemWithCachedSizes(
+      const FieldDescriptor* field,
+      const Message::Reflection* message_reflection,
+      io::CodedOutputStream* output);
+  static int MessageSetItemByteSize(
+      const FieldDescriptor* field,
+      const Message::Reflection* message_reflection);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat);
+};
+
+// inline methods ====================================================
+
+// This macro does the same thing as WireFormat::MakeTag(), but the
+// result is usable as a compile-time constant, which makes it usable
+// as a switch case or a template input.  WireFormat::MakeTag() is more
+// type-safe, though, so prefer it if possible.
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE)             \
+  static_cast<uint32>(                                              \
+    ((FIELD_NUMBER) << ::google::protobuf::internal::WireFormat::kTagTypeBits) | (TYPE))
+
+inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) {
+  return MakeTag(field->number(), WireTypeForFieldType(field->type()));
+}
+
+inline uint32 WireFormat::MakeTag(int field_number, WireType type) {
+  return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
+}
+
+inline WireFormat::WireType WireFormat::GetTagWireType(uint32 tag) {
+  return static_cast<WireType>(tag & kTagTypeMask);
+}
+
+inline int WireFormat::GetTagFieldNumber(uint32 tag) {
+  return static_cast<int>(tag >> kTagTypeBits);
+}
+
+inline uint32 WireFormat::EncodeFloat(float value) {
+  union {float f; uint32 i;};
+  f = value;
+  return i;
+}
+
+inline float WireFormat::DecodeFloat(uint32 value) {
+  union {float f; uint32 i;};
+  i = value;
+  return f;
+}
+
+inline uint64 WireFormat::EncodeDouble(double value) {
+  union {double f; uint64 i;};
+  f = value;
+  return i;
+}
+
+inline double WireFormat::DecodeDouble(uint64 value) {
+  union {double f; uint64 i;};
+  i = value;
+  return f;
+}
+
+// ZigZag Transform:  Encodes signed integers so that they can be
+// effectively used with varint encoding.
+//
+// varint operates on unsigned integers, encoding smaller numbers into
+// fewer bytes.  If you try to use it on a signed integer, it will treat
+// this number as a very large unsigned integer, which means that even
+// small signed numbers like -1 will take the maximum number of bytes
+// (10) to encode.  ZigZagEncode() maps signed integers to unsigned
+// in such a way that those with a small absolute value will have smaller
+// encoded values, making them appropriate for encoding using varint.
+//
+//       int32 ->     uint32
+// -------------------------
+//           0 ->          0
+//          -1 ->          1
+//           1 ->          2
+//          -2 ->          3
+//         ... ->        ...
+//  2147483647 -> 4294967294
+// -2147483648 -> 4294967295
+//
+//        >> encode >>
+//        << decode <<
+
+inline uint32 WireFormat::ZigZagEncode32(int32 n) {
+  // Note:  the right-shift must be arithmetic
+  return (n << 1) ^ (n >> 31);
+}
+
+inline int32 WireFormat::ZigZagDecode32(uint32 n) {
+  return (n >> 1) ^ -static_cast<int32>(n & 1);
+}
+
+inline uint64 WireFormat::ZigZagEncode64(int64 n) {
+  // Note:  the right-shift must be arithmetic
+  return (n << 1) ^ (n >> 63);
+}
+
+inline int64 WireFormat::ZigZagDecode64(uint64 n) {
+  return (n >> 1) ^ -static_cast<int64>(n & 1);
+}
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_H__
diff --git a/src/google/protobuf/wire_format_inl.h b/src/google/protobuf/wire_format_inl.h
new file mode 100644
index 0000000..d8cdd8d
--- /dev/null
+++ b/src/google/protobuf/wire_format_inl.h
@@ -0,0 +1,371 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__
+
+#include <string>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/coded_stream.h>
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline bool WireFormat::ReadInt32(io::CodedInputStream* input, int32* value) {
+  uint32 temp;
+  if (!input->ReadVarint32(&temp)) return false;
+  *value = static_cast<int32>(temp);
+  return true;
+}
+inline bool WireFormat::ReadInt64(io::CodedInputStream* input, int64* value) {
+  uint64 temp;
+  if (!input->ReadVarint64(&temp)) return false;
+  *value = static_cast<int64>(temp);
+  return true;
+}
+inline bool WireFormat::ReadUInt32(io::CodedInputStream* input, uint32* value) {
+  return input->ReadVarint32(value);
+}
+inline bool WireFormat::ReadUInt64(io::CodedInputStream* input, uint64* value) {
+  return input->ReadVarint64(value);
+}
+inline bool WireFormat::ReadSInt32(io::CodedInputStream* input, int32* value) {
+  uint32 temp;
+  if (!input->ReadVarint32(&temp)) return false;
+  *value = ZigZagDecode32(temp);
+  return true;
+}
+inline bool WireFormat::ReadSInt64(io::CodedInputStream* input, int64* value) {
+  uint64 temp;
+  if (!input->ReadVarint64(&temp)) return false;
+  *value = ZigZagDecode64(temp);
+  return true;
+}
+inline bool WireFormat::ReadFixed32(io::CodedInputStream* input,
+                                    uint32* value) {
+  return input->ReadLittleEndian32(value);
+}
+inline bool WireFormat::ReadFixed64(io::CodedInputStream* input,
+                                    uint64* value) {
+  return input->ReadLittleEndian64(value);
+}
+inline bool WireFormat::ReadSFixed32(io::CodedInputStream* input,
+                                     int32* value) {
+  uint32 temp;
+  if (!input->ReadLittleEndian32(&temp)) return false;
+  *value = static_cast<int32>(temp);
+  return true;
+}
+inline bool WireFormat::ReadSFixed64(io::CodedInputStream* input,
+                                     int64* value) {
+  uint64 temp;
+  if (!input->ReadLittleEndian64(&temp)) return false;
+  *value = static_cast<int64>(temp);
+  return true;
+}
+inline bool WireFormat::ReadFloat(io::CodedInputStream* input, float* value) {
+  uint32 temp;
+  if (!input->ReadLittleEndian32(&temp)) return false;
+  *value = DecodeFloat(temp);
+  return true;
+}
+inline bool WireFormat::ReadDouble(io::CodedInputStream* input, double* value) {
+  uint64 temp;
+  if (!input->ReadLittleEndian64(&temp)) return false;
+  *value = DecodeDouble(temp);
+  return true;
+}
+inline bool WireFormat::ReadBool(io::CodedInputStream* input, bool* value) {
+  uint32 temp;
+  if (!input->ReadVarint32(&temp)) return false;
+  *value = temp != 0;
+  return true;
+}
+inline bool WireFormat::ReadEnum(io::CodedInputStream* input, int* value) {
+  uint32 temp;
+  if (!input->ReadVarint32(&temp)) return false;
+  *value = static_cast<int>(temp);
+  return true;
+}
+
+inline bool WireFormat::ReadString(io::CodedInputStream* input, string* value) {
+  // WARNING:  In wire_format.cc, both strings and bytes are handled by
+  //   ReadString() to avoid code duplication.  If the implementations become
+  //   different, you will need to update that usage.
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  return input->ReadString(value, length);
+}
+inline bool WireFormat::ReadBytes(io::CodedInputStream* input, string* value) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  return input->ReadString(value, length);
+}
+
+
+inline bool WireFormat::ReadGroup(int field_number, io::CodedInputStream* input,
+                                  Message* value) {
+  if (!input->IncrementRecursionDepth()) return false;
+  if (!value->MergePartialFromCodedStream(input)) return false;
+  input->DecrementRecursionDepth();
+  // Make sure the last thing read was an end tag for this group.
+  if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
+    return false;
+  }
+  return true;
+}
+inline bool WireFormat::ReadMessage(io::CodedInputStream* input, Message* value) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  if (!input->IncrementRecursionDepth()) return false;
+  io::CodedInputStream::Limit limit = input->PushLimit(length);
+  if (!value->MergePartialFromCodedStream(input)) return false;
+  // Make sure that parsing stopped when the limit was hit, not at an endgroup
+  // tag.
+  if (!input->ConsumedEntireMessage()) return false;
+  input->PopLimit(limit);
+  input->DecrementRecursionDepth();
+  return true;
+}
+
+template<typename MessageType>
+inline bool WireFormat::ReadGroupNoVirtual(int field_number,
+                                           io::CodedInputStream* input,
+                                           MessageType* value) {
+  if (!input->IncrementRecursionDepth()) return false;
+  if (!value->MessageType::MergePartialFromCodedStream(input)) return false;
+  input->DecrementRecursionDepth();
+  // Make sure the last thing read was an end tag for this group.
+  if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
+    return false;
+  }
+  return true;
+}
+template<typename MessageType>
+inline bool WireFormat::ReadMessageNoVirtual(io::CodedInputStream* input,
+                                             MessageType* value) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  if (!input->IncrementRecursionDepth()) return false;
+  io::CodedInputStream::Limit limit = input->PushLimit(length);
+  if (!value->MessageType::MergePartialFromCodedStream(input)) return false;
+  // Make sure that parsing stopped when the limit was hit, not at an endgroup
+  // tag.
+  if (!input->ConsumedEntireMessage()) return false;
+  input->PopLimit(limit);
+  input->DecrementRecursionDepth();
+  return true;
+}
+
+// ===================================================================
+
+inline bool WireFormat::WriteTag(int field_number, WireType type,
+                                 io::CodedOutputStream* output) {
+  return output->WriteTag(MakeTag(field_number, type));
+}
+
+inline bool WireFormat::WriteInt32(int field_number, int32 value,
+                                   io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_VARINT, output) &&
+         output->WriteVarint32SignExtended(value);
+}
+inline bool WireFormat::WriteInt64(int field_number, int64 value,
+                                   io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_VARINT, output) &&
+         output->WriteVarint64(static_cast<uint64>(value));
+}
+inline bool WireFormat::WriteUInt32(int field_number, uint32 value,
+                                    io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_VARINT, output) &&
+         output->WriteVarint32(value);
+}
+inline bool WireFormat::WriteUInt64(int field_number, uint64 value,
+                                    io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_VARINT, output) &&
+         output->WriteVarint64(value);
+}
+inline bool WireFormat::WriteSInt32(int field_number, int32 value,
+                                    io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_VARINT, output) &&
+         output->WriteVarint32(ZigZagEncode32(value));
+}
+inline bool WireFormat::WriteSInt64(int field_number, int64 value,
+                                    io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_VARINT, output) &&
+         output->WriteVarint64(ZigZagEncode64(value));
+}
+inline bool WireFormat::WriteFixed32(int field_number, uint32 value,
+                                     io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_FIXED32, output) &&
+         output->WriteLittleEndian32(value);
+}
+inline bool WireFormat::WriteFixed64(int field_number, uint64 value,
+                                     io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_FIXED64, output) &&
+         output->WriteLittleEndian64(value);
+}
+inline bool WireFormat::WriteSFixed32(int field_number, int32 value,
+                                      io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_FIXED32, output) &&
+         output->WriteLittleEndian32(static_cast<uint32>(value));
+}
+inline bool WireFormat::WriteSFixed64(int field_number, int64 value,
+                                      io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_FIXED64, output) &&
+         output->WriteLittleEndian64(static_cast<uint64>(value));
+}
+inline bool WireFormat::WriteFloat(int field_number, float value,
+                                   io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_FIXED32, output) &&
+         output->WriteLittleEndian32(EncodeFloat(value));
+}
+inline bool WireFormat::WriteDouble(int field_number, double value,
+                                    io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_FIXED64, output) &&
+         output->WriteLittleEndian64(EncodeDouble(value));
+}
+inline bool WireFormat::WriteBool(int field_number, bool value,
+                                  io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_VARINT, output) &&
+         output->WriteVarint32(value ? 1 : 0);
+}
+inline bool WireFormat::WriteEnum(int field_number, int value,
+                                  io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_VARINT, output) &&
+         output->WriteVarint32SignExtended(value);
+}
+
+inline bool WireFormat::WriteString(int field_number, const string& value,
+                                    io::CodedOutputStream* output) {
+  // WARNING:  In wire_format.cc, both strings and bytes are handled by
+  //   WriteString() to avoid code duplication.  If the implementations become
+  //   different, you will need to update that usage.
+  return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) &&
+         output->WriteVarint32(value.size()) &&
+         output->WriteString(value);
+}
+inline bool WireFormat::WriteBytes(int field_number, const string& value,
+                                   io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) &&
+         output->WriteVarint32(value.size()) &&
+         output->WriteString(value);
+}
+
+
+inline bool WireFormat::WriteGroup(int field_number, const Message& value,
+                                   io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_START_GROUP, output) &&
+         value.SerializeWithCachedSizes(output) &&
+         WriteTag(field_number, WIRETYPE_END_GROUP, output);
+}
+inline bool WireFormat::WriteMessage(int field_number, const Message& value,
+                                     io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) &&
+         output->WriteVarint32(value.GetCachedSize()) &&
+         value.SerializeWithCachedSizes(output);
+}
+
+template<typename MessageType>
+inline bool WireFormat::WriteGroupNoVirtual(
+    int field_number, const MessageType& value,
+    io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_START_GROUP, output) &&
+         value.MessageType::SerializeWithCachedSizes(output) &&
+         WriteTag(field_number, WIRETYPE_END_GROUP, output);
+}
+template<typename MessageType>
+inline bool WireFormat::WriteMessageNoVirtual(
+    int field_number, const MessageType& value,
+    io::CodedOutputStream* output) {
+  return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) &&
+         output->WriteVarint32(value.MessageType::GetCachedSize()) &&
+         value.MessageType::SerializeWithCachedSizes(output);
+}
+
+// ===================================================================
+
+inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) {
+  int result = io::CodedOutputStream::VarintSize32(
+    field_number << kTagTypeBits);
+  if (type == FieldDescriptor::TYPE_GROUP) {
+    // Groups have both a start and an end tag.
+    return result * 2;
+  } else {
+    return result;
+  }
+}
+
+inline int WireFormat::Int32Size(int32 value) {
+  return io::CodedOutputStream::VarintSize32SignExtended(value);
+}
+inline int WireFormat::Int64Size(int64 value) {
+  return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
+}
+inline int WireFormat::UInt32Size(uint32 value) {
+  return io::CodedOutputStream::VarintSize32(value);
+}
+inline int WireFormat::UInt64Size(uint64 value) {
+  return io::CodedOutputStream::VarintSize64(value);
+}
+inline int WireFormat::SInt32Size(int32 value) {
+  return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
+}
+inline int WireFormat::SInt64Size(int64 value) {
+  return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
+}
+inline int WireFormat::EnumSize(int value) {
+  return io::CodedOutputStream::VarintSize32SignExtended(value);
+}
+
+inline int WireFormat::StringSize(const string& value) {
+  return io::CodedOutputStream::VarintSize32(value.size()) +
+         value.size();
+}
+inline int WireFormat::BytesSize(const string& value) {
+  return io::CodedOutputStream::VarintSize32(value.size()) +
+         value.size();
+}
+
+
+inline int WireFormat::GroupSize(const Message& value) {
+  return value.ByteSize();
+}
+inline int WireFormat::MessageSize(const Message& value) {
+  int size = value.ByteSize();
+  return io::CodedOutputStream::VarintSize32(size) + size;
+}
+
+template<typename MessageType>
+inline int WireFormat::GroupSizeNoVirtual(const MessageType& value) {
+  return value.MessageType::ByteSize();
+}
+template<typename MessageType>
+inline int WireFormat::MessageSizeNoVirtual(const MessageType& value) {
+  int size = value.MessageType::ByteSize();
+  return io::CodedOutputStream::VarintSize32(size) + size;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc
new file mode 100644
index 0000000..7430786
--- /dev/null
+++ b/src/google/protobuf/wire_format_unittest.cc
@@ -0,0 +1,526 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/wire_format_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_mset.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(WireFormatTest, MaxFieldNumber) {
+  // Make sure the max field number constant is accurate.
+  EXPECT_EQ((1 << (32 - WireFormat::kTagTypeBits)) - 1,
+            FieldDescriptor::kMaxNumber);
+}
+
+TEST(WireFormatTest, Parse) {
+  unittest::TestAllTypes source, dest;
+  string data;
+
+  // Serialize using the generated code.
+  TestUtil::SetAllFields(&source);
+  source.SerializeToString(&data);
+
+  // Parse using WireFormat.
+  io::ArrayInputStream raw_input(data.data(), data.size());
+  io::CodedInputStream input(&raw_input);
+  WireFormat::ParseAndMergePartial(unittest::TestAllTypes::descriptor(),
+                                   &input, dest.GetReflection());
+
+  // Check.
+  TestUtil::ExpectAllFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParseExtensions) {
+  unittest::TestAllExtensions source, dest;
+  string data;
+
+  // Serialize using the generated code.
+  TestUtil::SetAllExtensions(&source);
+  source.SerializeToString(&data);
+
+  // Parse using WireFormat.
+  io::ArrayInputStream raw_input(data.data(), data.size());
+  io::CodedInputStream input(&raw_input);
+  WireFormat::ParseAndMergePartial(unittest::TestAllExtensions::descriptor(),
+                                   &input, dest.GetReflection());
+
+  // Check.
+  TestUtil::ExpectAllExtensionsSet(dest);
+}
+
+TEST(WireFormatTest, ByteSize) {
+  unittest::TestAllTypes message;
+  TestUtil::SetAllFields(&message);
+
+  EXPECT_EQ(message.ByteSize(),
+            WireFormat::ByteSize(unittest::TestAllTypes::descriptor(),
+                                 message.GetReflection()));
+  message.Clear();
+  EXPECT_EQ(0, message.ByteSize());
+  EXPECT_EQ(0, WireFormat::ByteSize(unittest::TestAllTypes::descriptor(),
+                                    message.GetReflection()));
+}
+
+TEST(WireFormatTest, ByteSizeExtensions) {
+  unittest::TestAllExtensions message;
+  TestUtil::SetAllExtensions(&message);
+
+  EXPECT_EQ(message.ByteSize(),
+            WireFormat::ByteSize(unittest::TestAllExtensions::descriptor(),
+                                 message.GetReflection()));
+  message.Clear();
+  EXPECT_EQ(0, message.ByteSize());
+  EXPECT_EQ(0, WireFormat::ByteSize(unittest::TestAllExtensions::descriptor(),
+                                    message.GetReflection()));
+}
+
+TEST(WireFormatTest, Serialize) {
+  unittest::TestAllTypes message;
+  string generated_data;
+  string dynamic_data;
+
+  TestUtil::SetAllFields(&message);
+  int size = message.ByteSize();
+
+  // Serialize using the generated code.
+  {
+    io::StringOutputStream raw_output(&generated_data);
+    io::CodedOutputStream output(&raw_output);
+    message.SerializeWithCachedSizes(&output);
+  }
+
+  // Serialize using WireFormat.
+  {
+    io::StringOutputStream raw_output(&dynamic_data);
+    io::CodedOutputStream output(&raw_output);
+    WireFormat::SerializeWithCachedSizes(
+      unittest::TestAllTypes::descriptor(),
+      message.GetReflection(), size, &output);
+  }
+
+  // Should be the same.
+  // Don't use EXPECT_EQ here because we're comparing raw binary data and
+  // we really don't want it dumped to stdout on failure.
+  EXPECT_TRUE(dynamic_data == generated_data);
+}
+
+TEST(WireFormatTest, SerializeExtensions) {
+  unittest::TestAllExtensions message;
+  string generated_data;
+  string dynamic_data;
+
+  TestUtil::SetAllExtensions(&message);
+  int size = message.ByteSize();
+
+  // Serialize using the generated code.
+  {
+    io::StringOutputStream raw_output(&generated_data);
+    io::CodedOutputStream output(&raw_output);
+    message.SerializeWithCachedSizes(&output);
+  }
+
+  // Serialize using WireFormat.
+  {
+    io::StringOutputStream raw_output(&dynamic_data);
+    io::CodedOutputStream output(&raw_output);
+    WireFormat::SerializeWithCachedSizes(
+      unittest::TestAllExtensions::descriptor(),
+      message.GetReflection(), size, &output);
+  }
+
+  // Should be the same.
+  // Don't use EXPECT_EQ here because we're comparing raw binary data and
+  // we really don't want it dumped to stdout on failure.
+  EXPECT_TRUE(dynamic_data == generated_data);
+}
+
+TEST(WireFormatTest, SerializeFieldsAndExtensions) {
+  unittest::TestFieldOrderings message;
+  string generated_data;
+  string dynamic_data;
+
+  TestUtil::SetAllFieldsAndExtensions(&message);
+  int size = message.ByteSize();
+
+  // Serialize using the generated code.
+  {
+    io::StringOutputStream raw_output(&generated_data);
+    io::CodedOutputStream output(&raw_output);
+    message.SerializeWithCachedSizes(&output);
+  }
+
+  // Serialize using WireFormat.
+  {
+    io::StringOutputStream raw_output(&dynamic_data);
+    io::CodedOutputStream output(&raw_output);
+    WireFormat::SerializeWithCachedSizes(
+      unittest::TestFieldOrderings::descriptor(),
+      message.GetReflection(), size, &output);
+  }
+
+  // Should be the same.
+  // Don't use EXPECT_EQ here because we're comparing raw binary data and
+  // we really don't want it dumped to stdout on failure.
+  EXPECT_TRUE(dynamic_data == generated_data);
+
+  // Should output in canonical order.
+  TestUtil::ExpectAllFieldsAndExtensionsInOrder(dynamic_data);
+  TestUtil::ExpectAllFieldsAndExtensionsInOrder(generated_data);
+}
+
+const int kUnknownTypeId = 1550055;
+
+TEST(WireFormatTest, SerializeMessageSet) {
+  // Set up a TestMessageSet with two known messages and an unknown one.
+  unittest::TestMessageSet message_set;
+  message_set.MutableExtension(
+    unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
+  message_set.MutableExtension(
+    unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo");
+  message_set.mutable_unknown_fields()->AddField(kUnknownTypeId)
+                                      ->add_length_delimited("bar");
+
+  string data;
+  ASSERT_TRUE(message_set.SerializeToString(&data));
+
+  // Parse back using RawMessageSet and check the contents.
+  unittest::RawMessageSet raw;
+  ASSERT_TRUE(raw.ParseFromString(data));
+
+  EXPECT_EQ(0, raw.unknown_fields().field_count());
+
+  ASSERT_EQ(3, raw.item_size());
+  EXPECT_EQ(
+    unittest::TestMessageSetExtension1::descriptor()->extension(0)->number(),
+    raw.item(0).type_id());
+  EXPECT_EQ(
+    unittest::TestMessageSetExtension2::descriptor()->extension(0)->number(),
+    raw.item(1).type_id());
+  EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id());
+
+  unittest::TestMessageSetExtension1 message1;
+  EXPECT_TRUE(message1.ParseFromString(raw.item(0).message()));
+  EXPECT_EQ(123, message1.i());
+
+  unittest::TestMessageSetExtension2 message2;
+  EXPECT_TRUE(message2.ParseFromString(raw.item(1).message()));
+  EXPECT_EQ("foo", message2.str());
+
+  EXPECT_EQ("bar", raw.item(2).message());
+}
+
+TEST(WireFormatTest, ParseMessageSet) {
+  // Set up a RawMessageSet with two known messages and an unknown one.
+  unittest::RawMessageSet raw;
+
+  {
+    unittest::RawMessageSet::Item* item = raw.add_item();
+    item->set_type_id(
+      unittest::TestMessageSetExtension1::descriptor()->extension(0)->number());
+    unittest::TestMessageSetExtension1 message;
+    message.set_i(123);
+    message.SerializeToString(item->mutable_message());
+  }
+
+  {
+    unittest::RawMessageSet::Item* item = raw.add_item();
+    item->set_type_id(
+      unittest::TestMessageSetExtension2::descriptor()->extension(0)->number());
+    unittest::TestMessageSetExtension2 message;
+    message.set_str("foo");
+    message.SerializeToString(item->mutable_message());
+  }
+
+  {
+    unittest::RawMessageSet::Item* item = raw.add_item();
+    item->set_type_id(kUnknownTypeId);
+    item->set_message("bar");
+  }
+
+  string data;
+  ASSERT_TRUE(raw.SerializeToString(&data));
+
+  // Parse as a TestMessageSet and check the contents.
+  unittest::TestMessageSet message_set;
+  ASSERT_TRUE(message_set.ParseFromString(data));
+
+  EXPECT_EQ(123, message_set.GetExtension(
+    unittest::TestMessageSetExtension1::message_set_extension).i());
+  EXPECT_EQ("foo", message_set.GetExtension(
+    unittest::TestMessageSetExtension2::message_set_extension).str());
+
+  ASSERT_EQ(1, message_set.unknown_fields().field_count());
+  ASSERT_EQ(1, message_set.unknown_fields().field(0).length_delimited_size());
+  EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited(0));
+}
+
+TEST(WireFormatTest, RecursionLimit) {
+  unittest::TestRecursiveMessage message;
+  message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1);
+  string data;
+  message.SerializeToString(&data);
+
+  {
+    io::ArrayInputStream raw_input(data.data(), data.size());
+    io::CodedInputStream input(&raw_input);
+    input.SetRecursionLimit(4);
+    unittest::TestRecursiveMessage message2;
+    EXPECT_TRUE(message2.ParseFromCodedStream(&input));
+  }
+
+  {
+    io::ArrayInputStream raw_input(data.data(), data.size());
+    io::CodedInputStream input(&raw_input);
+    input.SetRecursionLimit(3);
+    unittest::TestRecursiveMessage message2;
+    EXPECT_FALSE(message2.ParseFromCodedStream(&input));
+  }
+}
+
+TEST(WireFormatTest, UnknownFieldRecursionLimit) {
+  unittest::TestEmptyMessage message;
+  message.mutable_unknown_fields()
+        ->AddField(1234)->add_group()
+        ->AddField(1234)->add_group()
+        ->AddField(1234)->add_group()
+        ->AddField(1234)->add_group()
+        ->AddField(1234)->add_varint(123);
+  string data;
+  message.SerializeToString(&data);
+
+  {
+    io::ArrayInputStream raw_input(data.data(), data.size());
+    io::CodedInputStream input(&raw_input);
+    input.SetRecursionLimit(4);
+    unittest::TestEmptyMessage message2;
+    EXPECT_TRUE(message2.ParseFromCodedStream(&input));
+  }
+
+  {
+    io::ArrayInputStream raw_input(data.data(), data.size());
+    io::CodedInputStream input(&raw_input);
+    input.SetRecursionLimit(3);
+    unittest::TestEmptyMessage message2;
+    EXPECT_FALSE(message2.ParseFromCodedStream(&input));
+  }
+}
+
+TEST(WireFormatTest, ZigZag) {
+// avoid line-wrapping
+#define LL(x) GOOGLE_LONGLONG(x)
+#define ULL(x) GOOGLE_ULONGLONG(x)
+#define ZigZagEncode32(x) WireFormat::ZigZagEncode32(x)
+#define ZigZagDecode32(x) WireFormat::ZigZagDecode32(x)
+#define ZigZagEncode64(x) WireFormat::ZigZagEncode64(x)
+#define ZigZagDecode64(x) WireFormat::ZigZagDecode64(x)
+
+  EXPECT_EQ(0u, ZigZagEncode32( 0));
+  EXPECT_EQ(1u, ZigZagEncode32(-1));
+  EXPECT_EQ(2u, ZigZagEncode32( 1));
+  EXPECT_EQ(3u, ZigZagEncode32(-2));
+  EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF));
+  EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000));
+  EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF));
+  EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000));
+
+  EXPECT_EQ( 0, ZigZagDecode32(0u));
+  EXPECT_EQ(-1, ZigZagDecode32(1u));
+  EXPECT_EQ( 1, ZigZagDecode32(2u));
+  EXPECT_EQ(-2, ZigZagDecode32(3u));
+  EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu));
+  EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu));
+  EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu));
+  EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu));
+
+  EXPECT_EQ(0u, ZigZagEncode64( 0));
+  EXPECT_EQ(1u, ZigZagEncode64(-1));
+  EXPECT_EQ(2u, ZigZagEncode64( 1));
+  EXPECT_EQ(3u, ZigZagEncode64(-2));
+  EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF)));
+  EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000)));
+  EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF)));
+  EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000)));
+  EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF)));
+  EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000)));
+
+  EXPECT_EQ( 0, ZigZagDecode64(0u));
+  EXPECT_EQ(-1, ZigZagDecode64(1u));
+  EXPECT_EQ( 1, ZigZagDecode64(2u));
+  EXPECT_EQ(-2, ZigZagDecode64(3u));
+  EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE)));
+  EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF)));
+  EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE)));
+  EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF)));
+  EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE)));
+  EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF)));
+
+  // Some easier-to-verify round-trip tests.  The inputs (other than 0, 1, -1)
+  // were chosen semi-randomly via keyboard bashing.
+  EXPECT_EQ(    0, ZigZagDecode32(ZigZagEncode32(    0)));
+  EXPECT_EQ(    1, ZigZagDecode32(ZigZagEncode32(    1)));
+  EXPECT_EQ(   -1, ZigZagDecode32(ZigZagEncode32(   -1)));
+  EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927)));
+  EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612)));
+
+  EXPECT_EQ(    0, ZigZagDecode64(ZigZagEncode64(    0)));
+  EXPECT_EQ(    1, ZigZagDecode64(ZigZagEncode64(    1)));
+  EXPECT_EQ(   -1, ZigZagDecode64(ZigZagEncode64(   -1)));
+  EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927)));
+  EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612)));
+
+  EXPECT_EQ(LL(856912304801416), ZigZagDecode64(ZigZagEncode64(
+            LL(856912304801416))));
+  EXPECT_EQ(LL(-75123905439571256), ZigZagDecode64(ZigZagEncode64(
+            LL(-75123905439571256))));
+}
+
+class WireFormatInvalidInputTest : public testing::Test {
+ protected:
+  // Make a serialized TestAllTypes in which the field optional_nested_message
+  // contains exactly the given bytes, which may be invalid.
+  string MakeInvalidEmbeddedMessage(const char* bytes, int size) {
+    const FieldDescriptor* field =
+      unittest::TestAllTypes::descriptor()->FindFieldByName(
+        "optional_nested_message");
+    GOOGLE_CHECK(field != NULL);
+
+    string result;
+
+    {
+      io::StringOutputStream raw_output(&result);
+      io::CodedOutputStream output(&raw_output);
+
+      EXPECT_TRUE(WireFormat::WriteString(
+        field->number(), string(bytes, size), &output));
+    }
+
+    return result;
+  }
+
+  // Make a serialized TestAllTypes in which the field optionalgroup
+  // contains exactly the given bytes -- which may be invalid -- and
+  // possibly no end tag.
+  string MakeInvalidGroup(const char* bytes, int size, bool include_end_tag) {
+    const FieldDescriptor* field =
+      unittest::TestAllTypes::descriptor()->FindFieldByName(
+        "optionalgroup");
+    GOOGLE_CHECK(field != NULL);
+
+    string result;
+
+    {
+      io::StringOutputStream raw_output(&result);
+      io::CodedOutputStream output(&raw_output);
+
+      EXPECT_TRUE(output.WriteVarint32(WireFormat::MakeTag(field)));
+      EXPECT_TRUE(output.WriteString(string(bytes, size)));
+      if (include_end_tag) {
+        EXPECT_TRUE(
+          output.WriteVarint32(WireFormat::MakeTag(
+            field->number(), WireFormat::WIRETYPE_END_GROUP)));
+      }
+    }
+
+    return result;
+  }
+};
+
+TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) {
+  unittest::TestAllTypes message;
+
+  // Control case.
+  EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0)));
+
+  // The byte is a valid varint, but not a valid tag (zero).
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1)));
+
+  // The byte is a malformed varint.
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1)));
+
+  // The byte is an endgroup tag, but we aren't parsing a group.
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1)));
+
+  // The byte is a valid varint but not a valid tag (bad wire type).
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1)));
+}
+
+TEST_F(WireFormatInvalidInputTest, InvalidGroup) {
+  unittest::TestAllTypes message;
+
+  // Control case.
+  EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
+
+  // Missing end tag.  Groups cannot end at EOF.
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
+
+  // The byte is a valid varint, but not a valid tag (zero).
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
+
+  // The byte is a malformed varint.
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
+
+  // The byte is an endgroup tag, but not the right one for this group.
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
+
+  // The byte is a valid varint but not a valid tag (bad wire type).
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
+}
+
+TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) {
+  // Use ForeignMessage so that the group made by MakeInvalidGroup will not
+  // be a known tag number.
+  unittest::ForeignMessage message;
+
+  // Control case.
+  EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
+
+  // Missing end tag.  Groups cannot end at EOF.
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
+
+  // The byte is a valid varint, but not a valid tag (zero).
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
+
+  // The byte is a malformed varint.
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
+
+  // The byte is an endgroup tag, but not the right one for this group.
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
+
+  // The byte is a valid varint but not a valid tag (bad wire type).
+  EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
+}
+
+}  // namespace
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/gtest/CHANGES b/src/gtest/CHANGES
new file mode 100644
index 0000000..871ef1f
--- /dev/null
+++ b/src/gtest/CHANGES
@@ -0,0 +1,3 @@
+Changes for 1.0.0:
+
+ * Initial Open Source release of Google Test
diff --git a/src/gtest/CONTRIBUTORS b/src/gtest/CONTRIBUTORS
new file mode 100644
index 0000000..3134183
--- /dev/null
+++ b/src/gtest/CONTRIBUTORS
@@ -0,0 +1,23 @@
+# This file contains a list of people who've made non-trivial
+# contribution to the Google C++ Testing Framework project.  People
+# who commit code to the project are encouraged to add their names
+# here.  Please keep the list sorted by first names.
+
+Ajay Joshi <jaj@google.com>
+Bharat Mediratta <bharat@menalto.com>
+Chandler Carruth <chandlerc@google.com>
+Chris Prince <cprince@google.com>
+Chris Taylor <taylorc@google.com>
+Jeffrey Yasskin <jyasskin@google.com>
+Keir Mierle <mierle@gmail.com>
+Keith Ray <keith.ray@gmail.com>
+Markus Heule <markus.heule@gmail.com>
+Patrick Hanna <phanna@google.com>
+Patrick Riley <pfr@google.com>
+Peter Kaminski <piotrk@google.com>
+Russ Cox <rsc@google.com>
+Russ Rufer <russ@pentad.com>
+Sean Mcafee <eefacm@gmail.com>
+Sigurður Ásgeirsson <siggi@google.com>
+Tracy Bialik <tracy@pentad.com>
+Zhanyong Wan <wan@google.com>
diff --git a/src/gtest/COPYING b/src/gtest/COPYING
new file mode 100644
index 0000000..1941a11
--- /dev/null
+++ b/src/gtest/COPYING
@@ -0,0 +1,28 @@
+Copyright 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/gtest/README b/src/gtest/README
new file mode 100644
index 0000000..0e17047
--- /dev/null
+++ b/src/gtest/README
@@ -0,0 +1,150 @@
+This directory contains Google Test, described below.  It is used by the
+Protocol Buffer C++ unit tests.  If you would like to use Google Test
+yourself, you should probably download it from the URL mentioned below,
+not attempt to use the sources in this package.
+
+Two changes were made from the original sources:
+* gtest.cc's #include of gtest-internal-inl.h was modified to reflect the
+  environment it is being built in (replaced "src/" with "gtest/").
+* GetThreadCount() in gtest-port.h was hard-coded to return 1 rather than 0,
+  since the Protocol Buffer tests do not use threads.
+
+The original Google Test README follows.
+
+======================================================================
+
+Google C++ Testing Framework
+============================
+http://code.google.com/p/googletest/
+
+Overview
+--------
+Google's framework for writing C++ tests on a variety of platforms (Linux, Mac
+OS X, Windows, Windows CE, and Symbian). Based on the xUnit architecture.
+Supports automatic test discovery, a rich set of assertions, user-defined
+assertions, death tests, fatal and non-fatal failures, various options for
+running the tests, and XML test report generation.
+
+Please see the project page above for more information as well as mailing lists
+for questions, discussions, and development. There is also an IRC channel on
+OFTC (irc.oftc.net) #gtest available. Please join us!
+
+Requirements
+------------
+Google Test is designed to have fairly minimal requirements to build and use
+with your projects, but there are some. Currently, the only Operating System
+(OS) on which Google Test is known to build properly is Linux, but we are
+actively working on Windows and Mac support as well. The source code itself is
+already portable across many other platforms, but we are still developing
+robust build systems for each.
+
+### Linux Requirements ###
+These are the base requirements to build and use Google Test from a source
+package (as described below):
+  * GNU-compatible Make or "gmake"
+  * POSIX-standard shell
+  * POSIX(-2) Regular Expressions (regex.h)
+  * A C++98 standards compliant compiler
+
+Furthermore, if you are building Google Test from a VCS Checkout (also
+described below), there are further requirements:
+  * Automake version 1.9 or newer
+  * Autoconf version 2.59 or newer
+  * Libtool / Libtoolize
+  * Python version 2.4 or newer
+
+Getting the Source
+------------------
+There are two primary ways of getting Google Test's source code: you can
+download a source release in your preferred archive format, or directly check
+out the source from a Version Control System (VCS, we use Google Code's
+Subversion hosting). The VCS checkout requires a few extra steps and some extra
+software packages on your system, but lets you track development, and make
+patches to contribute much more easily, so we highly encourage it.
+
+### VCS Checkout: ###
+The first step is to select whether you want to check out the main line of
+development on Google Test, or one of the released branches. The former will be
+much more active and have the latest features, but the latter provides much
+more stability and predictability. Choose whichever fits your needs best, and
+proceed with the following Subversion commands:
+
+  $ svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn
+
+or for a release version X.Y.*'s branch:
+
+  $ svn checkout http://googletest.googlecode.com/svn/branches/release-X.Y/ gtest-X.Y-svn
+
+Next you will need to prepare the GNU Autotools build system. Enter the
+target directory of the checkout command you used ('gtest-svn' or
+'gtest-X.Y-svn' above) and proceed with the following commands:
+
+  $ aclocal-1.9  # Where "1.9" must match the following automake command
+  $ libtoolize -c
+  $ autoheader
+  $ automake-1.9 -ac  # See Automake version requirements above
+  $ autoconf
+
+While this is a bit complicated, it will most often be automatically re-run by
+your "make" invocations, so in practice you shouldn't need to worry too much.
+Once you have completed these steps, your VCS checkout should be equivalent to
+a source package, and you may continue with those directions, skipping over the
+acquiring and unpacking of the source itself, as the VCS has done that for you.
+
+### Source Package: ###
+Google Test is also released in source packages which can be downloaded from
+its Google Code download page[1]. Several different archive formats are
+provided, but the only difference is the tools used to manipulate them, and the
+size of the resulting file. Download whichever you are most comfortable with.
+
+  [1] Google Test Downloads: http://code.google.com/p/googletest/downloads/list
+
+Once downloaded expand the archive using whichever tools you prefer for that
+type. This will always result in a new directory with the name "gtest-X.Y.Z"
+which contains all of the source code. Here are some examples in Linux:
+
+  $ tar -xvzf gtest-X.Y.Z.tar.gz
+  $ tar -xvjf gtest-X.Y.Z.tar.bz2
+  $ unzip gtest-X.Y.Z.zip
+
+Building the Source
+-------------------
+There are two primary options for building the source at this point: build it
+inside the source code tree, or in a separate directory. We recommend building
+in a separate directory as that tends to produce both more consistent results
+and be easier to clean up should anything go wrong, but both patterns are
+supported. The only hard restriction is that while the build directory can be
+a subdirectory of the source directory, the opposite is not possible and will
+result in errors. Once you have selected where you wish to build Google Test,
+create the directory if necessary, and enter it. The following steps apply for
+either approach by simply substituting the shell variable SRCDIR with "." for
+building inside the source directory, and the relative path to the source
+directory otherwise.
+
+  $ ${SRCDIR}/configure  # Standard GNU configure script, --help for more info
+  $ make  # Standard makefile following GNU conventions
+
+Other programs will only be able to use Google Test's functionality if you
+install it in a location which they can access, in Linux this is typically
+under '/usr/local'. The following command will install all of the Google Test
+libraries, public headers, and utilities necessary for other programs and
+libraries to leverage it:
+
+  $ sudo make install  # Not necessary, but allows use by other programs
+
+TODO(chandlerc@google.com): This section needs to be expanded when the
+'gtest-config' script is finished and Autoconf macro's are provided (or not
+provided) in order to properly reflect the process for other programs to
+locate, include, and link against Google Test.
+
+Finally, should you need to remove Google Test from your system after having
+installed it, run the following command, and it will back out its changes.
+However, note carefully that you must run this command on the *same* Google
+Test build that you ran the install from, or the results are not predictable.
+If you install Google Test on your system, and are working from a VCS checkout,
+make sure you run this *before* updating your checkout of the source in order
+to uninstall the same version which you installed.
+
+  $ sudo make uninstall  # Must be run against the exact same build as "install"
+
+Happy testing!
diff --git a/src/gtest/gen_gtest_pred_impl.py b/src/gtest/gen_gtest_pred_impl.py
new file mode 100755
index 0000000..7cb31da
--- /dev/null
+++ b/src/gtest/gen_gtest_pred_impl.py
@@ -0,0 +1,733 @@
+#!/usr/bin/python2.4
+#
+# Copyright 2006, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""gen_gtest_pred_impl.py v0.1
+
+Generates the implementation of Google Test predicate assertions and
+accompanying tests.
+
+Usage:
+
+  gen_gtest_pred_impl.py MAX_ARITY
+
+where MAX_ARITY is a positive integer.
+
+The command generates the implementation of up-to MAX_ARITY-ary
+predicate assertions, and writes it to file gtest_pred_impl.h in the
+directory where the script is.  It also generates the accompanying
+unit test in file gtest_pred_impl_unittest.cc.
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import sys
+import time
+
+# Where this script is.
+SCRIPT_DIR = os.path.dirname(sys.argv[0])
+
+# Where to store the generated header.
+HEADER = os.path.join(SCRIPT_DIR, '../include/gtest/gtest_pred_impl.h')
+
+# Where to store the generated unit test.
+UNIT_TEST = os.path.join(SCRIPT_DIR, '../test/gtest_pred_impl_unittest.cc')
+
+
+def HeaderPreamble(n):
+  """Returns the preamble for the header file.
+
+  Args:
+    n:  the maximum arity of the predicate macros to be generated.
+  """
+
+  # A map that defines the values used in the preamble template.
+  DEFS = {
+    'today' : time.strftime('%m/%d/%Y'),
+    'year' : time.strftime('%Y'),
+    'command' : '%s %s' % (os.path.basename(sys.argv[0]), n),
+    'n' : n
+    }
+
+  return (
+"""// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is AUTOMATICALLY GENERATED on %(today)s by command
+// '%(command)s'.  DO NOT EDIT BY HAND!
+//
+// Implements a family of generic predicate assertion macros.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+
+// Makes sure this header is not included before gtest.h.
+#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
+#error Do not include gtest_pred_impl.h directly.  Include gtest.h instead.
+#endif  // GTEST_INCLUDE_GTEST_GTEST_H_
+
+// This header implements a family of generic predicate assertion
+// macros:
+//
+//   ASSERT_PRED_FORMAT1(pred_format, v1)
+//   ASSERT_PRED_FORMAT2(pred_format, v1, v2)
+//   ...
+//
+// where pred_format is a function or functor that takes n (in the
+// case of ASSERT_PRED_FORMATn) values and their source expression
+// text, and returns a testing::AssertionResult.  See the definition
+// of ASSERT_EQ in gtest.h for an example.
+//
+// If you don't care about formatting, you can use the more
+// restrictive version:
+//
+//   ASSERT_PRED1(pred, v1)
+//   ASSERT_PRED2(pred, v1, v2)
+//   ...
+//
+// where pred is an n-ary function or functor that returns bool,
+// and the values v1, v2, ..., must support the << operator for
+// streaming to std::ostream.
+//
+// We also define the EXPECT_* variations.
+//
+// For now we only support predicates whose arity is at most %(n)s.
+// Please email googletestframework@googlegroups.com if you need
+// support for higher arities.
+
+// GTEST_ASSERT is the basic statement to which all of the assertions
+// in this file reduce.  Don't use this in your code.
+
+#define GTEST_ASSERT(expression, on_failure) \\
+  GTEST_AMBIGUOUS_ELSE_BLOCKER \\
+  if (const ::testing::AssertionResult gtest_ar = (expression)) \\
+    ; \\
+  else \\
+    on_failure(gtest_ar.failure_message())
+""" % DEFS)
+
+
+def Arity(n):
+  """Returns the English name of the given arity."""
+
+  if n < 0:
+    return None
+  elif n <= 3:
+    return ['nullary', 'unary', 'binary', 'ternary'][n]
+  else:
+    return '%s-ary' % n
+
+
+def Title(word):
+  """Returns the given word in title case.  The difference between
+  this and string's title() method is that Title('4-ary') is '4-ary'
+  while '4-ary'.title() is '4-Ary'."""
+
+  return word[0].upper() + word[1:]
+
+
+def OneTo(n):
+  """Returns the list [1, 2, 3, ..., n]."""
+
+  return range(1, n + 1)
+
+
+def Iter(n, format, sep=''):
+  """Given a positive integer n, a format string that contains 0 or
+  more '%s' format specs, and optionally a separator string, returns
+  the join of n strings, each formatted with the format string on an
+  iterator ranged from 1 to n.
+
+  Example:
+
+  Iter(3, 'v%s', sep=', ') returns 'v1, v2, v3'.
+  """
+
+  # How many '%s' specs are in format?
+  spec_count = len(format.split('%s')) - 1
+  return sep.join([format % (spec_count * (i,)) for i in OneTo(n)])
+
+
+def ImplementationForArity(n):
+  """Returns the implementation of n-ary predicate assertions."""
+
+  # A map the defines the values used in the implementation template.
+  DEFS = {
+    'n' : str(n),
+    'vs' : Iter(n, 'v%s', sep=', '),
+    'vts' : Iter(n, '#v%s', sep=', '),
+    'arity' : Arity(n),
+    'Arity' : Title(Arity(n))
+    }
+
+  impl = """
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED%(n)s.  Don't use
+// this in your code.
+template <typename Pred""" % DEFS
+
+  impl += Iter(n, """,
+          typename T%s""")
+
+  impl += """>
+AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS
+
+  impl += Iter(n, """,
+                                  const char* e%s""")
+
+  impl += """,
+                                  Pred pred"""
+
+  impl += Iter(n, """,
+                                  const T%s& v%s""")
+
+  impl += """) {
+  if (pred(%(vs)s)) return AssertionSuccess();
+
+  Message msg;
+""" % DEFS
+
+  impl += '  msg << pred_text << "("'
+
+  impl += Iter(n, """
+      << e%s""", sep=' << ", "')
+
+  impl += ' << ") evaluates to false, where"'
+
+  impl += Iter(n, """
+      << "\\n" << e%s << " evaluates to " << v%s""")
+
+  impl += """;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT%(n)s(pred_format, %(vs)s, on_failure)\\
+  GTEST_ASSERT(pred_format(%(vts)s, %(vs)s),\\
+               on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s.  Don't use
+// this in your code.
+#define GTEST_PRED%(n)s(pred, %(vs)s, on_failure)\\
+  GTEST_ASSERT(::testing::AssertPred%(n)sHelper(#pred""" % DEFS
+
+  impl += Iter(n, """, \\
+                                 #v%s""")
+
+  impl += """, \\
+                                 pred"""
+
+  impl += Iter(n, """, \\
+                                 v%s""")
+
+  impl += """), on_failure)
+
+// %(Arity)s predicate assertion macros.
+#define EXPECT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\
+  GTEST_PRED_FORMAT%(n)s(pred_format, %(vs)s, GTEST_NONFATAL_FAILURE)
+#define EXPECT_PRED%(n)s(pred, %(vs)s) \\
+  GTEST_PRED%(n)s(pred, %(vs)s, GTEST_NONFATAL_FAILURE)
+#define ASSERT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\
+  GTEST_PRED_FORMAT%(n)s(pred_format, %(vs)s, GTEST_FATAL_FAILURE)
+#define ASSERT_PRED%(n)s(pred, %(vs)s) \\
+  GTEST_PRED%(n)s(pred, %(vs)s, GTEST_FATAL_FAILURE)
+
+""" % DEFS
+
+  return impl
+
+
+def HeaderPostamble():
+  """Returns the postamble for the header file."""
+
+  return """
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+"""
+
+
+def GenerateFile(path, content):
+  """Given a file path and a content string, overwrites it with the
+  given content."""
+
+  print 'Updating file %s . . .' % path
+
+  f = file(path, 'w+')
+  print >>f, content,
+  f.close()
+
+  print 'File %s has been updated.' % path
+
+
+def GenerateHeader(n):
+  """Given the maximum arity n, updates the header file that implements
+  the predicate assertions."""
+
+  GenerateFile(HEADER,
+               HeaderPreamble(n)
+               + ''.join([ImplementationForArity(i) for i in OneTo(n)])
+               + HeaderPostamble())
+
+
+def UnitTestPreamble():
+  """Returns the preamble for the unit test file."""
+
+  # A map that defines the values used in the preamble template.
+  DEFS = {
+    'today' : time.strftime('%m/%d/%Y'),
+    'year' : time.strftime('%Y'),
+    'command' : '%s %s' % (os.path.basename(sys.argv[0]), sys.argv[1]),
+    }
+
+  return (
+"""// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is AUTOMATICALLY GENERATED on %(today)s by command
+// '%(command)s'.  DO NOT EDIT BY HAND!
+
+// Regression test for gtest_pred_impl.h
+//
+// This file is generated by a script and quite long.  If you intend to
+// learn how Google Test works by reading its unit tests, read
+// gtest_unittest.cc instead.
+//
+// This is intended as a regression test for the Google Test predicate
+// assertions.  We compile it as part of the gtest_unittest target
+// only to keep the implementation tidy and compact, as it is quite
+// involved to set up the stage for testing Google Test using Google
+// Test itself.
+//
+// Currently, gtest_unittest takes ~11 seconds to run in the testing
+// daemon.  In the future, if it grows too large and needs much more
+// time to finish, we should consider separating this file into a
+// stand-alone regression test.
+
+#include <iostream>
+
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+// A user-defined data type.
+struct Bool {
+  explicit Bool(int val) : value(val != 0) {}
+
+  bool operator>(int n) const { return value > Bool(n).value; }
+
+  Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); }
+
+  bool operator==(const Bool& rhs) const { return value == rhs.value; }
+
+  bool value;
+};
+
+// Enables Bool to be used in assertions.
+std::ostream& operator<<(std::ostream& os, const Bool& x) {
+  return os << (x.value ? "true" : "false");
+}
+
+""" % DEFS)
+
+
+def TestsForArity(n):
+  """Returns the tests for n-ary predicate assertions."""
+
+  # A map that defines the values used in the template for the tests.
+  DEFS = {
+    'n' : n,
+    'es' : Iter(n, 'e%s', sep=', '),
+    'vs' : Iter(n, 'v%s', sep=', '),
+    'vts' : Iter(n, '#v%s', sep=', '),
+    'tvs' : Iter(n, 'T%s v%s', sep=', '),
+    'int_vs' : Iter(n, 'int v%s', sep=', '),
+    'Bool_vs' : Iter(n, 'Bool v%s', sep=', '),
+    'types' : Iter(n, 'typename T%s', sep=', '),
+    'v_sum' : Iter(n, 'v%s', sep=' + '),
+    'arity' : Arity(n),
+    'Arity' : Title(Arity(n)),
+    }
+
+  tests = (
+"""// Sample functions/functors for testing %(arity)s predicate assertions.
+
+// A %(arity)s predicate function.
+template <%(types)s>
+bool PredFunction%(n)s(%(tvs)s) {
+  return %(v_sum)s > 0;
+}
+
+// The following two functions are needed to circumvent a bug in
+// gcc 2.95.3, which sometimes has problem with the above template
+// function.
+bool PredFunction%(n)sInt(%(int_vs)s) {
+  return %(v_sum)s > 0;
+}
+bool PredFunction%(n)sBool(%(Bool_vs)s) {
+  return %(v_sum)s > 0;
+}
+""" % DEFS)
+
+  tests += """
+// A %(arity)s predicate functor.
+struct PredFunctor%(n)s {
+  template <%(types)s>
+  bool operator()(""" % DEFS
+
+  tests += Iter(n, 'const T%s& v%s', sep=""",
+                  """)
+
+  tests += """) {
+    return %(v_sum)s > 0;
+  }
+};
+""" % DEFS
+
+  tests += """
+// A %(arity)s predicate-formatter function.
+template <%(types)s>
+testing::AssertionResult PredFormatFunction%(n)s(""" % DEFS
+
+  tests += Iter(n, 'const char* e%s', sep=""",
+                                             """)
+
+  tests += Iter(n, """,
+                                             const T%s& v%s""")
+
+  tests += """) {
+  if (PredFunction%(n)s(%(vs)s))
+    return testing::AssertionSuccess();
+
+  testing::Message msg;
+  msg << """ % DEFS
+
+  tests += Iter(n, 'e%s', sep=' << " + " << ')
+
+  tests += """
+      << " is expected to be positive, but evaluates to "
+      << %(v_sum)s << ".";
+  return testing::AssertionFailure(msg);
+}
+""" % DEFS
+
+  tests += """
+// A %(arity)s predicate-formatter functor.
+struct PredFormatFunctor%(n)s {
+  template <%(types)s>
+  testing::AssertionResult operator()(""" % DEFS
+
+  tests += Iter(n, 'const char* e%s', sep=""",
+                                      """)
+
+  tests += Iter(n, """,
+                                      const T%s& v%s""")
+
+  tests += """) const {
+    return PredFormatFunction%(n)s(%(es)s, %(vs)s);
+  }
+};
+""" % DEFS
+
+  tests += """
+// Tests for {EXPECT|ASSERT}_PRED_FORMAT%(n)s.
+
+class Predicate%(n)sTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    expected_to_finish_ = true;
+    finished_ = false;""" % DEFS
+
+  tests += """
+    """ + Iter(n, 'n%s_ = ') + """0;
+  }
+"""
+
+  tests += """
+  virtual void TearDown() {
+    // Verifies that each of the predicate's arguments was evaluated
+    // exactly once."""
+
+  tests += ''.join(["""
+    EXPECT_EQ(1, n%s_) <<
+        "The predicate assertion didn't evaluate argument %s "
+        "exactly once.";""" % (i, i + 1) for i in OneTo(n)])
+
+  tests += """
+
+    // Verifies that the control flow in the test function is expected.
+    if (expected_to_finish_ && !finished_) {
+      FAIL() << "The predicate assertion unexpactedly aborted the test.";
+    } else if (!expected_to_finish_ && finished_) {
+      FAIL() << "The failed predicate assertion didn't abort the test "
+                "as expected.";
+    }
+  }
+
+  // true iff the test function is expected to run to finish.
+  static bool expected_to_finish_;
+
+  // true iff the test function did run to finish.
+  static bool finished_;
+""" % DEFS
+
+  tests += Iter(n, """
+  static int n%s_;""")
+
+  tests += """
+};
+
+bool Predicate%(n)sTest::expected_to_finish_;
+bool Predicate%(n)sTest::finished_;
+""" % DEFS
+
+  tests += Iter(n, """int Predicate%%(n)sTest::n%s_;
+""") % DEFS
+
+  tests += """
+typedef Predicate%(n)sTest EXPECT_PRED_FORMAT%(n)sTest;
+typedef Predicate%(n)sTest ASSERT_PRED_FORMAT%(n)sTest;
+typedef Predicate%(n)sTest EXPECT_PRED%(n)sTest;
+typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest;
+""" % DEFS
+
+  def GenTest(use_format, use_assert, expect_failure,
+              use_functor, use_user_type):
+    """Returns the test for a predicate assertion macro.
+
+    Args:
+      use_format:     true iff the assertion is a *_PRED_FORMAT*.
+      use_assert:     true iff the assertion is a ASSERT_*.
+      expect_failure: true iff the assertion is expected to fail.
+      use_functor:    true iff the first argument of the assertion is
+                      a functor (as opposed to a function)
+      use_user_type:  true iff the predicate functor/function takes
+                      argument(s) of a user-defined type.
+
+    Example:
+
+      GenTest(1, 0, 0, 1, 0) returns a test that tests the behavior
+      of a successful EXPECT_PRED_FORMATn() that takes a functor
+      whose arguments have built-in types."""
+
+    if use_assert:
+      assrt = 'ASSERT'  # 'assert' is reserved, so we cannot use
+                        # that identifier here.
+    else:
+      assrt = 'EXPECT'
+
+    assertion = assrt + '_PRED'
+
+    if use_format:
+      pred_format = 'PredFormat'
+      assertion += '_FORMAT'
+    else:
+      pred_format = 'Pred'
+
+    assertion += '%(n)s' % DEFS
+
+    if use_functor:
+      pred_format_type = 'functor'
+      pred_format += 'Functor%(n)s()'
+    else:
+      pred_format_type = 'function'
+      pred_format += 'Function%(n)s'
+      if not use_format:
+        if use_user_type:
+          pred_format += 'Bool'
+        else:
+          pred_format += 'Int'
+
+    test_name = pred_format_type.title()
+
+    if use_user_type:
+      arg_type = 'user-defined type (Bool)'
+      test_name += 'OnUserType'
+      if expect_failure:
+        arg = 'Bool(n%s_++)'
+      else:
+        arg = 'Bool(++n%s_)'
+    else:
+      arg_type = 'built-in type (int)'
+      test_name += 'OnBuiltInType'
+      if expect_failure:
+        arg = 'n%s_++'
+      else:
+        arg = '++n%s_'
+
+    if expect_failure:
+      successful_or_failed = 'failed'
+      expected_or_not = 'expected.'
+      test_name +=  'Failure'
+    else:
+      successful_or_failed = 'successful'
+      expected_or_not = 'UNEXPECTED!'
+      test_name +=  'Success'
+
+    # A map that defines the values used in the test template.
+    defs = DEFS.copy()
+    defs.update({
+      'assert' : assrt,
+      'assertion' : assertion,
+      'test_name' : test_name,
+      'pf_type' : pred_format_type,
+      'pf' : pred_format,
+      'arg_type' : arg_type,
+      'arg' : arg,
+      'successful' : successful_or_failed,
+      'expected' : expected_or_not,
+      })
+
+    test = """
+// Tests a %(successful)s %(assertion)s where the
+// predicate-formatter is a %(pf_type)s on a %(arg_type)s.
+TEST_F(%(assertion)sTest, %(test_name)s) {""" % defs
+
+    indent = (len(assertion) + 3)*' '
+    extra_indent = ''
+
+    if expect_failure:
+      extra_indent = '  '
+      if use_assert:
+        test += """
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT"""
+      else:
+        test += """
+  EXPECT_NONFATAL_FAILURE({  // NOLINT"""
+
+    test += '\n' + extra_indent + """  %(assertion)s(%(pf)s""" % defs
+
+    test = test % defs
+    test += Iter(n, ',\n' + indent + extra_indent + '%(arg)s' % defs)
+    test += ');\n' + extra_indent + '  finished_ = true;\n'
+
+    if expect_failure:
+      test += '  }, "");\n'
+
+    test += '}\n'
+    return test
+
+  # Generates tests for all 2**6 = 64 combinations.
+  tests += ''.join([GenTest(use_format, use_assert, expect_failure,
+                            use_functor, use_user_type)
+                    for use_format in [0, 1]
+                    for use_assert in [0, 1]
+                    for expect_failure in [0, 1]
+                    for use_functor in [0, 1]
+                    for use_user_type in [0, 1]
+                    ])
+
+  return tests
+
+
+def UnitTestPostamble():
+  """Returns the postamble for the tests."""
+
+  return ''
+
+
+def GenerateUnitTest(n):
+  """Returns the tests for up-to n-ary predicate assertions."""
+
+  GenerateFile(UNIT_TEST,
+               UnitTestPreamble()
+               + ''.join([TestsForArity(i) for i in OneTo(n)])
+               + UnitTestPostamble())
+
+
+def _Main():
+  """The entry point of the script.  Generates the header file and its
+  unit test."""
+
+  if len(sys.argv) != 2:
+    print __doc__
+    print 'Author: ' + __author__
+    sys.exit(1)
+
+  n = int(sys.argv[1])
+  GenerateHeader(n)
+  GenerateUnitTest(n)
+
+
+if __name__ == '__main__':
+  _Main()
diff --git a/src/gtest/gtest-death-test.cc b/src/gtest/gtest-death-test.cc
new file mode 100644
index 0000000..09fdd3f
--- /dev/null
+++ b/src/gtest/gtest-death-test.cc
@@ -0,0 +1,751 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// This file implements death tests.
+
+#include <gtest/gtest-death-test.h>
+#include <gtest/internal/gtest-port.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#include <gtest/gtest-message.h>
+#include <gtest/internal/gtest-string.h>
+
+// Indicates that this translation unit is part of Google Test's
+// implementation.  It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error.  This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION
+#include "gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION
+
+namespace testing {
+
+// Constants.
+
+// The default death test style.
+static const char kDefaultDeathTestStyle[] = "fast";
+
+GTEST_DEFINE_string(
+    death_test_style,
+    internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle),
+    "Indicates how to run a death test in a forked child process: "
+    "\"threadsafe\" (child process re-executes the test binary "
+    "from the beginning, running only the specific death test) or "
+    "\"fast\" (child process runs the death test immediately "
+    "after forking).");
+
+namespace internal {
+GTEST_DEFINE_string(
+    internal_run_death_test, "",
+    "Indicates the file, line number, temporal index of "
+    "the single death test to run, and a file descriptor to "
+    "which a success code may be sent, all separated by "
+    "colons.  This flag is specified if and only if the current "
+    "process is a sub-process launched for running a thread-safe "
+    "death test.  FOR INTERNAL USE ONLY.");
+}  // namespace internal
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// ExitedWithCode constructor.
+ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
+}
+
+// ExitedWithCode function-call operator.
+bool ExitedWithCode::operator()(int exit_status) const {
+  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
+}
+
+// KilledBySignal constructor.
+KilledBySignal::KilledBySignal(int signum) : signum_(signum) {
+}
+
+// KilledBySignal function-call operator.
+bool KilledBySignal::operator()(int exit_status) const {
+  return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
+}
+
+namespace internal {
+
+// Utilities needed for death tests.
+
+// Generates a textual description of a given exit code, in the format
+// specified by wait(2).
+static String ExitSummary(int exit_code) {
+  Message m;
+  if (WIFEXITED(exit_code)) {
+    m << "Exited with exit status " << WEXITSTATUS(exit_code);
+  } else if (WIFSIGNALED(exit_code)) {
+    m << "Terminated by signal " << WTERMSIG(exit_code);
+  }
+#ifdef WCOREDUMP
+  if (WCOREDUMP(exit_code)) {
+    m << " (core dumped)";
+  }
+#endif
+  return m.GetString();
+}
+
+// Returns true if exit_status describes a process that was terminated
+// by a signal, or exited normally with a nonzero exit code.
+bool ExitedUnsuccessfully(int exit_status) {
+  return !ExitedWithCode(0)(exit_status);
+}
+
+// Generates a textual failure message when a death test finds more than
+// one thread running, or cannot determine the number of threads, prior
+// to executing the given statement.  It is the responsibility of the
+// caller not to pass a thread_count of 1.
+static String DeathTestThreadWarning(size_t thread_count) {
+  Message msg;
+  msg << "Death tests use fork(), which is unsafe particularly"
+      << " in a threaded context. For this test, " << GTEST_NAME << " ";
+  if (thread_count == 0)
+    msg << "couldn't detect the number of threads.";
+  else
+    msg << "detected " << thread_count << " threads.";
+  return msg.GetString();
+}
+
+// Static string containing a description of the outcome of the
+// last death test.
+static String last_death_test_message;
+
+// Flag characters for reporting a death test that did not die.
+static const char kDeathTestLived = 'L';
+static const char kDeathTestReturned = 'R';
+static const char kDeathTestInternalError = 'I';
+
+// An enumeration describing all of the possible ways that a death test
+// can conclude.  DIED means that the process died while executing the
+// test code; LIVED means that process lived beyond the end of the test
+// code; and RETURNED means that the test statement attempted a "return,"
+// which is not allowed.  IN_PROGRESS means the test has not yet
+// concluded.
+enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED };
+
+// Routine for aborting the program which is safe to call from an
+// exec-style death test child process, in which case the the error
+// message is propagated back to the parent process.  Otherwise, the
+// message is simply printed to stderr.  In either case, the program
+// then exits with status 1.
+void DeathTestAbort(const char* format, ...) {
+  // This function may be called from a threadsafe-style death test
+  // child process, which operates on a very small stack.  Use the
+  // heap for any additional non-miniscule memory requirements.
+  const InternalRunDeathTestFlag* const flag =
+      GetUnitTestImpl()->internal_run_death_test_flag();
+  va_list args;
+  va_start(args, format);
+
+  if (flag != NULL) {
+    FILE* parent = fdopen(flag->status_fd, "w");
+    fputc(kDeathTestInternalError, parent);
+    vfprintf(parent, format, args);
+    fclose(parent);
+    va_end(args);
+    _exit(1);
+  } else {
+    vfprintf(stderr, format, args);
+    va_end(args);
+    abort();
+  }
+}
+
+// A replacement for CHECK that calls DeathTestAbort if the assertion
+// fails.
+#define GTEST_DEATH_TEST_CHECK(expression) \
+  do { \
+    if (!(expression)) { \
+      DeathTestAbort("CHECK failed: File %s, line %d: %s", \
+                     __FILE__, __LINE__, #expression); \
+    } \
+  } while (0)
+
+// This macro is similar to GTEST_DEATH_TEST_CHECK, but it is meant for
+// evaluating any system call that fulfills two conditions: it must return
+// -1 on failure, and set errno to EINTR when it is interrupted and
+// should be tried again.  The macro expands to a loop that repeatedly
+// evaluates the expression as long as it evaluates to -1 and sets
+// errno to EINTR.  If the expression evaluates to -1 but errno is
+// something other than EINTR, DeathTestAbort is called.
+#define GTEST_DEATH_TEST_CHECK_SYSCALL(expression) \
+  do { \
+    int retval; \
+    do { \
+      retval = (expression); \
+    } while (retval == -1 && errno == EINTR); \
+    if (retval == -1) { \
+      DeathTestAbort("CHECK failed: File %s, line %d: %s != -1", \
+                     __FILE__, __LINE__, #expression); \
+    } \
+  } while (0)
+
+// Death test constructor.  Increments the running death test count
+// for the current test.
+DeathTest::DeathTest() {
+  TestInfo* const info = GetUnitTestImpl()->current_test_info();
+  if (info == NULL) {
+    DeathTestAbort("Cannot run a death test outside of a TEST or "
+                   "TEST_F construct");
+  }
+}
+
+// Creates and returns a death test by dispatching to the current
+// death test factory.
+bool DeathTest::Create(const char* statement, const RE* regex,
+                       const char* file, int line, DeathTest** test) {
+  return GetUnitTestImpl()->death_test_factory()->Create(
+      statement, regex, file, line, test);
+}
+
+const char* DeathTest::LastMessage() {
+  return last_death_test_message.c_str();
+}
+
+// ForkingDeathTest provides implementations for most of the abstract
+// methods of the DeathTest interface.  Only the AssumeRole method is
+// left undefined.
+class ForkingDeathTest : public DeathTest {
+ public:
+  ForkingDeathTest(const char* statement, const RE* regex);
+
+  // All of these virtual functions are inherited from DeathTest.
+  virtual int Wait();
+  virtual bool Passed(bool status_ok);
+  virtual void Abort(AbortReason reason);
+
+ protected:
+  void set_forked(bool forked) { forked_ = forked; }
+  void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
+  void set_read_fd(int fd) { read_fd_ = fd; }
+  void set_write_fd(int fd) { write_fd_ = fd; }
+
+ private:
+  // The textual content of the code this object is testing.
+  const char* const statement_;
+  // The regular expression which test output must match.
+  const RE* const regex_;
+  // True if the death test successfully forked.
+  bool forked_;
+  // PID of child process during death test; 0 in the child process itself.
+  pid_t child_pid_;
+  // File descriptors for communicating the death test's status byte.
+  int read_fd_;   // Always -1 in the child process.
+  int write_fd_;  // Always -1 in the parent process.
+  // The exit status of the child process.
+  int status_;
+  // How the death test concluded.
+  DeathTestOutcome outcome_;
+};
+
+// Constructs a ForkingDeathTest.
+ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex)
+    : DeathTest(),
+      statement_(statement),
+      regex_(regex),
+      forked_(false),
+      child_pid_(-1),
+      read_fd_(-1),
+      write_fd_(-1),
+      status_(-1),
+      outcome_(IN_PROGRESS) {
+}
+
+// Reads an internal failure message from a file descriptor, then calls
+// LOG(FATAL) with that message.  Called from a death test parent process
+// to read a failure message from the death test child process.
+static void FailFromInternalError(int fd) {
+  Message error;
+  char buffer[256];
+  ssize_t num_read;
+
+  do {
+    while ((num_read = read(fd, buffer, 255)) > 0) {
+      buffer[num_read] = '\0';
+      error << buffer;
+    }
+  } while (num_read == -1 && errno == EINTR);
+
+  // TODO(smcafee):  Maybe just FAIL the test instead?
+  if (num_read == 0) {
+    GTEST_LOG(FATAL, error);
+  } else {
+    GTEST_LOG(FATAL,
+              Message() << "Error while reading death test internal: "
+              << strerror(errno) << " [" << errno << "]");
+  }
+}
+
+// Waits for the child in a death test to exit, returning its exit
+// status, or 0 if no child process exists.  As a side effect, sets the
+// outcome data member.
+int ForkingDeathTest::Wait() {
+  if (!forked_)
+    return 0;
+
+  // The read() here blocks until data is available (signifying the
+  // failure of the death test) or until the pipe is closed (signifying
+  // its success), so it's okay to call this in the parent before
+  // the child process has exited.
+  char flag;
+  ssize_t bytes_read;
+
+  do {
+    bytes_read = read(read_fd_, &flag, 1);
+  } while (bytes_read == -1 && errno == EINTR);
+
+  if (bytes_read == 0) {
+    outcome_ = DIED;
+  } else if (bytes_read == 1) {
+    switch (flag) {
+      case kDeathTestReturned:
+        outcome_ = RETURNED;
+        break;
+      case kDeathTestLived:
+        outcome_ = LIVED;
+        break;
+      case kDeathTestInternalError:
+        FailFromInternalError(read_fd_);  // Does not return.
+        break;
+      default:
+        GTEST_LOG(FATAL,
+                  Message() << "Death test child process reported unexpected "
+                  << "status byte (" << static_cast<unsigned int>(flag)
+                  << ")");
+    }
+  } else {
+    GTEST_LOG(FATAL,
+              Message() << "Read from death test child process failed: "
+              << strerror(errno));
+  }
+
+  GTEST_DEATH_TEST_CHECK_SYSCALL(close(read_fd_));
+  GTEST_DEATH_TEST_CHECK_SYSCALL(waitpid(child_pid_, &status_, 0));
+  return status_;
+}
+
+// Assesses the success or failure of a death test, using both private
+// members which have previously been set, and one argument:
+//
+// Private data members:
+//   outcome:  an enumeration describing how the death test
+//             concluded: DIED, LIVED, or RETURNED.  The death test fails
+//             in the latter two cases
+//   status:   the exit status of the child process, in the format
+//             specified by wait(2)
+//   regex:    a regular expression object to be applied to
+//             the test's captured standard error output; the death test
+//             fails if it does not match
+//
+// Argument:
+//   status_ok: true if exit_status is acceptable in the context of
+//              this particular death test, which fails if it is false
+//
+// Returns true iff all of the above conditions are met.  Otherwise, the
+// first failing condition, in the order given above, is the one that is
+// reported. Also sets the static variable last_death_test_message.
+bool ForkingDeathTest::Passed(bool status_ok) {
+  if (!forked_)
+    return false;
+
+#if GTEST_HAS_GLOBAL_STRING
+  const ::string error_message = GetCapturedStderr();
+#else
+  const ::std::string error_message = GetCapturedStderr();
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  bool success = false;
+  Message buffer;
+
+  buffer << "Death test: " << statement_ << "\n";
+  switch (outcome_) {
+    case LIVED:
+      buffer << "    Result: failed to die.\n"
+             << " Error msg: " << error_message;
+      break;
+    case RETURNED:
+      buffer << "    Result: illegal return in test statement.\n"
+             << " Error msg: " << error_message;
+      break;
+    case DIED:
+      if (status_ok) {
+        if (RE::PartialMatch(error_message, *regex_)) {
+          success = true;
+        } else {
+          buffer << "    Result: died but not with expected error.\n"
+                 << "  Expected: " << regex_->pattern() << "\n"
+                 << "Actual msg: " << error_message;
+        }
+      } else {
+        buffer << "    Result: died but not with expected exit code:\n"
+               << "            " << ExitSummary(status_) << "\n";
+      }
+      break;
+    default:
+      GTEST_LOG(FATAL,
+                "DeathTest::Passed somehow called before conclusion of test");
+  }
+
+  last_death_test_message = buffer.GetString();
+  return success;
+}
+
+// Signals that the death test code which should have exited, didn't.
+// Should be called only in a death test child process.
+// Writes a status byte to the child's status file desriptor, then
+// calls _exit(1).
+void ForkingDeathTest::Abort(AbortReason reason) {
+  // The parent process considers the death test to be a failure if
+  // it finds any data in our pipe.  So, here we write a single flag byte
+  // to the pipe, then exit.
+  const char flag =
+      reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned;
+  GTEST_DEATH_TEST_CHECK_SYSCALL(write(write_fd_, &flag, 1));
+  GTEST_DEATH_TEST_CHECK_SYSCALL(close(write_fd_));
+  _exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash)
+}
+
+// A concrete death test class that forks, then immediately runs the test
+// in the child process.
+class NoExecDeathTest : public ForkingDeathTest {
+ public:
+  NoExecDeathTest(const char* statement, const RE* regex) :
+      ForkingDeathTest(statement, regex) { }
+  virtual TestRole AssumeRole();
+};
+
+// The AssumeRole process for a fork-and-run death test.  It implements a
+// straightforward fork, with a simple pipe to transmit the status byte.
+DeathTest::TestRole NoExecDeathTest::AssumeRole() {
+  const size_t thread_count = GetThreadCount();
+  if (thread_count != 1) {
+    GTEST_LOG(WARNING, DeathTestThreadWarning(thread_count));
+  }
+
+  int pipe_fd[2];
+  GTEST_DEATH_TEST_CHECK(pipe(pipe_fd) != -1);
+
+  last_death_test_message = "";
+  CaptureStderr();
+  // When we fork the process below, the log file buffers are copied, but the
+  // file descriptors are shared.  We flush all log files here so that closing
+  // the file descriptors in the child process doesn't throw off the
+  // synchronization between descriptors and buffers in the parent process.
+  // This is as close to the fork as possible to avoid a race condition in case
+  // there are multiple threads running before the death test, and another
+  // thread writes to the log file.
+  FlushInfoLog();
+
+  const pid_t child_pid = fork();
+  GTEST_DEATH_TEST_CHECK(child_pid != -1);
+  set_child_pid(child_pid);
+  if (child_pid == 0) {
+    GTEST_DEATH_TEST_CHECK_SYSCALL(close(pipe_fd[0]));
+    set_write_fd(pipe_fd[1]);
+    // Redirects all logging to stderr in the child process to prevent
+    // concurrent writes to the log files.  We capture stderr in the parent
+    // process and append the child process' output to a log.
+    LogToStderr();
+    return EXECUTE_TEST;
+  } else {
+    GTEST_DEATH_TEST_CHECK_SYSCALL(close(pipe_fd[1]));
+    set_read_fd(pipe_fd[0]);
+    set_forked(true);
+    return OVERSEE_TEST;
+  }
+}
+
+// A concrete death test class that forks and re-executes the main
+// program from the beginning, with command-line flags set that cause
+// only this specific death test to be run.
+class ExecDeathTest : public ForkingDeathTest {
+ public:
+  ExecDeathTest(const char* statement, const RE* regex,
+                const char* file, int line) :
+      ForkingDeathTest(statement, regex), file_(file), line_(line) { }
+  virtual TestRole AssumeRole();
+ private:
+  // The name of the file in which the death test is located.
+  const char* const file_;
+  // The line number on which the death test is located.
+  const int line_;
+};
+
+// Utility class for accumulating command-line arguments.
+class Arguments {
+ public:
+  Arguments() {
+    args_.push_back(NULL);
+  }
+  ~Arguments() {
+    for (std::vector<char*>::iterator i = args_.begin();
+         i + 1 != args_.end();
+         ++i) {
+      free(*i);
+    }
+  }
+  void AddArgument(const char* argument) {
+    args_.insert(args_.end() - 1, strdup(argument));
+  }
+
+  template <typename Str>
+  void AddArguments(const ::std::vector<Str>& arguments) {
+    for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
+         i != arguments.end();
+         ++i) {
+      args_.insert(args_.end() - 1, strdup(i->c_str()));
+    }
+  }
+  char* const* Argv() {
+    return &args_[0];
+  }
+ private:
+  std::vector<char*> args_;
+};
+
+// A struct that encompasses the arguments to the child process of a
+// threadsafe-style death test process.
+struct ExecDeathTestArgs {
+  char* const* argv;  // Command-line arguments for the child's call to exec
+  int close_fd;       // File descriptor to close; the read end of a pipe
+};
+
+// The main function for a threadsafe-style death test child process.
+static int ExecDeathTestChildMain(void* child_arg) {
+  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);
+  GTEST_DEATH_TEST_CHECK_SYSCALL(close(args->close_fd));
+  execve(args->argv[0], args->argv, environ);
+  DeathTestAbort("execve failed: %s", strerror(errno));
+  return EXIT_FAILURE;
+}
+
+// Two utility routines that together determine the direction the stack
+// grows.
+// This could be accomplished more elegantly by a single recursive
+// function, but we want to guard against the unlikely possibility of
+// a smart compiler optimizing the recursion away.
+static bool StackLowerThanAddress(const void* ptr) {
+  int dummy;
+  return &dummy < ptr;
+}
+
+static bool StackGrowsDown() {
+  int dummy;
+  return StackLowerThanAddress(&dummy);
+}
+
+// A threadsafe implementation of fork(2) for threadsafe-style death tests
+// that uses clone(2).  It dies with an error message if anything goes
+// wrong.
+static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
+  static const bool stack_grows_down = StackGrowsDown();
+  const size_t stack_size = getpagesize();
+  void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
+                           MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  GTEST_DEATH_TEST_CHECK(stack != MAP_FAILED);
+  void* const stack_top =
+      static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0);
+  ExecDeathTestArgs args = { argv, close_fd };
+  const pid_t child_pid = clone(&ExecDeathTestChildMain, stack_top,
+                                SIGCHLD, &args);
+  GTEST_DEATH_TEST_CHECK(child_pid != -1);
+  GTEST_DEATH_TEST_CHECK(munmap(stack, stack_size) != -1);
+  return child_pid;
+}
+
+// The AssumeRole process for a fork-and-exec death test.  It re-executes the
+// main program from the beginning, setting the --gtest_filter
+// and --gtest_internal_run_death_test flags to cause only the current
+// death test to be re-run.
+DeathTest::TestRole ExecDeathTest::AssumeRole() {
+  const UnitTestImpl* const impl = GetUnitTestImpl();
+  const InternalRunDeathTestFlag* const flag =
+      impl->internal_run_death_test_flag();
+  const TestInfo* const info = impl->current_test_info();
+  const int death_test_index = info->result()->death_test_count();
+
+  if (flag != NULL) {
+    set_write_fd(flag->status_fd);
+    return EXECUTE_TEST;
+  }
+
+  int pipe_fd[2];
+  GTEST_DEATH_TEST_CHECK(pipe(pipe_fd) != -1);
+  // Clear the close-on-exec flag on the write end of the pipe, lest
+  // it be closed when the child process does an exec:
+  GTEST_DEATH_TEST_CHECK(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
+
+  const String filter_flag =
+      String::Format("--%s%s=%s.%s",
+                     GTEST_FLAG_PREFIX, kFilterFlag,
+                     info->test_case_name(), info->name());
+  const String internal_flag =
+      String::Format("--%s%s=%s:%d:%d:%d",
+                     GTEST_FLAG_PREFIX, kInternalRunDeathTestFlag, file_, line_,
+                     death_test_index, pipe_fd[1]);
+  Arguments args;
+  args.AddArguments(GetArgvs());
+  args.AddArgument("--logtostderr");
+  args.AddArgument(filter_flag.c_str());
+  args.AddArgument(internal_flag.c_str());
+
+  last_death_test_message = "";
+
+  CaptureStderr();
+  // See the comment in NoExecDeathTest::AssumeRole for why the next line
+  // is necessary.
+  FlushInfoLog();
+
+  const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]);
+  GTEST_DEATH_TEST_CHECK_SYSCALL(close(pipe_fd[1]));
+  set_child_pid(child_pid);
+  set_read_fd(pipe_fd[0]);
+  set_forked(true);
+  return OVERSEE_TEST;
+}
+
+// Creates a concrete DeathTest-derived class that depends on the
+// --gtest_death_test_style flag, and sets the pointer pointed to
+// by the "test" argument to its address.  If the test should be
+// skipped, sets that pointer to NULL.  Returns true, unless the
+// flag is set to an invalid value.
+bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
+                                     const char* file, int line,
+                                     DeathTest** test) {
+  UnitTestImpl* const impl = GetUnitTestImpl();
+  const InternalRunDeathTestFlag* const flag =
+      impl->internal_run_death_test_flag();
+  const int death_test_index = impl->current_test_info()
+      ->increment_death_test_count();
+
+  if (flag != NULL) {
+    if (death_test_index > flag->index) {
+      last_death_test_message = String::Format(
+          "Death test count (%d) somehow exceeded expected maximum (%d)",
+          death_test_index, flag->index);
+      return false;
+    }
+
+    if (!(flag->file == file && flag->line == line &&
+          flag->index == death_test_index)) {
+      *test = NULL;
+      return true;
+    }
+  }
+
+  if (GTEST_FLAG(death_test_style) == "threadsafe") {
+    *test = new ExecDeathTest(statement, regex, file, line);
+  } else if (GTEST_FLAG(death_test_style) == "fast") {
+    *test = new NoExecDeathTest(statement, regex);
+  } else {
+    last_death_test_message = String::Format(
+        "Unknown death test style \"%s\" encountered",
+        GTEST_FLAG(death_test_style).c_str());
+    return false;
+  }
+
+  return true;
+}
+
+// Splits a given string on a given delimiter, populating a given
+// vector with the fields.  GTEST_HAS_DEATH_TEST implies that we have
+// ::std::string, so we can use it here.
+static void SplitString(const ::std::string& str, char delimiter,
+                        ::std::vector< ::std::string>* dest) {
+  ::std::vector< ::std::string> parsed;
+  ::std::string::size_type pos = 0;
+  while (true) {
+    const ::std::string::size_type colon = str.find(':', pos);
+    if (colon == ::std::string::npos) {
+      parsed.push_back(str.substr(pos));
+      break;
+    } else {
+      parsed.push_back(str.substr(pos, colon - pos));
+      pos = colon + 1;
+    }
+  }
+  dest->swap(parsed);
+}
+
+// Attempts to parse a string into a positive integer.  Returns true
+// if that is possible.  GTEST_HAS_DEATH_TEST implies that we have
+// ::std::string, so we can use it here.
+static bool ParsePositiveInt(const ::std::string& str, int* number) {
+  // Fail fast if the given string does not begin with a digit;
+  // this bypasses strtol's "optional leading whitespace and plus
+  // or minus sign" semantics, which are undesirable here.
+  if (str.empty() || !isdigit(str[0])) {
+    return false;
+  }
+  char* endptr;
+  const long parsed = strtol(str.c_str(), &endptr, 10);  // NOLINT
+  if (*endptr == '\0' && parsed <= INT_MAX) {
+    *number = static_cast<int>(parsed);
+    return true;
+  } else {
+    return false;
+  }
+}
+
+// Returns a newly created InternalRunDeathTestFlag object with fields
+// initialized from the GTEST_FLAG(internal_run_death_test) flag if
+// the flag is specified; otherwise returns NULL.
+InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
+  if (GTEST_FLAG(internal_run_death_test) == "") return NULL;
+
+  InternalRunDeathTestFlag* const internal_run_death_test_flag =
+      new InternalRunDeathTestFlag;
+  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
+  // can use it here.
+  ::std::vector< ::std::string> fields;
+  SplitString(GTEST_FLAG(internal_run_death_test).c_str(), ':', &fields);
+  if (fields.size() != 4
+      || !ParsePositiveInt(fields[1], &internal_run_death_test_flag->line)
+      || !ParsePositiveInt(fields[2], &internal_run_death_test_flag->index)
+      || !ParsePositiveInt(fields[3],
+                           &internal_run_death_test_flag->status_fd)) {
+    DeathTestAbort("Bad --gtest_internal_run_death_test flag: %s",
+                   GTEST_FLAG(internal_run_death_test).c_str());
+  }
+  internal_run_death_test_flag->file = fields[0].c_str();
+  return internal_run_death_test_flag;
+}
+
+}  // namespace internal
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace testing
diff --git a/src/gtest/gtest-death-test.h b/src/gtest/gtest-death-test.h
new file mode 100644
index 0000000..cbd41fe
--- /dev/null
+++ b/src/gtest/gtest-death-test.h
@@ -0,0 +1,205 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the public API for death tests.  It is
+// #included by gtest.h so a user doesn't need to include this
+// directly.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+
+#include <gtest/internal/gtest-death-test-internal.h>
+
+namespace testing {
+
+// This flag controls the style of death tests.  Valid values are "threadsafe",
+// meaning that the death test child process will re-execute the test binary
+// from the start, running only a single death test, or "fast",
+// meaning that the child process will execute the test logic immediately
+// after forking.
+GTEST_DECLARE_string(death_test_style);
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// The following macros are useful for writing death tests.
+
+// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
+// executed:
+//
+//   1. The assertion fails immediately if there are more than one
+//   active threads.  This is because it's safe to fork() only when
+//   there is a single thread.
+//
+//   2. The parent process forks a sub-process and runs the death test
+//   in it; the sub-process exits with code 0 at the end of the death
+//   test, if it hasn't exited already.
+//
+//   3. The parent process waits for the sub-process to terminate.
+//
+//   4. The parent process checks the exit code and error message of
+//   the sub-process.
+//
+// Note:
+//
+// It's not safe to call exit() if the current process is forked from
+// a multi-threaded process, so people usually call _exit() instead in
+// such a case.  However, we are not concerned with this as we run
+// death tests only when there is a single thread.  Since exit() has a
+// cleaner semantics (it also calls functions registered with atexit()
+// and on_exit()), this macro calls exit() instead of _exit() to
+// terminate the child process.
+//
+// Examples:
+//
+//   ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
+//   for (int i = 0; i < 5; i++) {
+//     EXPECT_DEATH(server.ProcessRequest(i),
+//                  "Invalid request .* in ProcessRequest()")
+//         << "Failed to die on request " << i);
+//   }
+//
+//   ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
+//
+//   bool KilledBySIGHUP(int exit_code) {
+//     return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
+//   }
+//
+//   ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
+
+// Asserts that a given statement causes the program to exit, with an
+// integer exit status that satisfies predicate, and emitting error output
+// that matches regex.
+#define ASSERT_EXIT(statement, predicate, regex) \
+  GTEST_DEATH_TEST(statement, predicate, regex, GTEST_FATAL_FAILURE)
+
+// Like ASSERT_EXIT, but continues on to successive tests in the
+// test case, if any:
+#define EXPECT_EXIT(statement, predicate, regex) \
+  GTEST_DEATH_TEST(statement, predicate, regex, GTEST_NONFATAL_FAILURE)
+
+// Asserts that a given statement causes the program to exit, either by
+// explicitly exiting with a nonzero exit code or being killed by a
+// signal, and emitting error output that matches regex.
+#define ASSERT_DEATH(statement, regex) \
+  ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
+
+// Like ASSERT_DEATH, but continues on to successive tests in the
+// test case, if any:
+#define EXPECT_DEATH(statement, regex) \
+  EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
+
+// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
+
+// Tests that an exit code describes a normal exit with a given exit code.
+class ExitedWithCode {
+ public:
+  explicit ExitedWithCode(int exit_code);
+  bool operator()(int exit_status) const;
+ private:
+  const int exit_code_;
+};
+
+// Tests that an exit code describes an exit due to termination by a
+// given signal.
+class KilledBySignal {
+ public:
+  explicit KilledBySignal(int signum);
+  bool operator()(int exit_status) const;
+ private:
+  const int signum_;
+};
+
+// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
+// The death testing framework causes this to have interesting semantics,
+// since the sideeffects of the call are only visible in opt mode, and not
+// in debug mode.
+//
+// In practice, this can be used to test functions that utilize the
+// LOG(DFATAL) macro using the following style:
+//
+// int DieInDebugOr12(int* sideeffect) {
+//   if (sideeffect) {
+//     *sideeffect = 12;
+//   }
+//   LOG(DFATAL) << "death";
+//   return 12;
+// }
+//
+// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
+//   int sideeffect = 0;
+//   // Only asserts in dbg.
+//   EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
+//
+// #ifdef NDEBUG
+//   // opt-mode has sideeffect visible.
+//   EXPECT_EQ(12, sideeffect);
+// #else
+//   // dbg-mode no visible sideeffect.
+//   EXPECT_EQ(0, sideeffect);
+// #endif
+// }
+//
+// This will assert that DieInDebugReturn12InOpt() crashes in debug
+// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
+// appropriate fallback value (12 in this case) in opt mode. If you
+// need to test that a function has appropriate side-effects in opt
+// mode, include assertions against the side-effects.  A general
+// pattern for this is:
+//
+// EXPECT_DEBUG_DEATH({
+//   // Side-effects here will have an effect after this statement in
+//   // opt mode, but none in debug mode.
+//   EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
+// }, "death");
+//
+#ifdef NDEBUG
+
+#define EXPECT_DEBUG_DEATH(statement, regex) \
+  do { statement; } while (false)
+
+#define ASSERT_DEBUG_DEATH(statement, regex) \
+  do { statement; } while (false)
+
+#else
+
+#define EXPECT_DEBUG_DEATH(statement, regex) \
+  EXPECT_DEATH(statement, regex)
+
+#define ASSERT_DEBUG_DEATH(statement, regex) \
+  ASSERT_DEATH(statement, regex)
+
+#endif  // NDEBUG for EXPECT_DEBUG_DEATH
+#endif  // GTEST_HAS_DEATH_TEST
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
diff --git a/src/gtest/gtest-filepath.cc b/src/gtest/gtest-filepath.cc
new file mode 100644
index 0000000..2fba96e
--- /dev/null
+++ b/src/gtest/gtest-filepath.cc
@@ -0,0 +1,208 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: keith.ray@gmail.com (Keith Ray)
+
+#include <gtest/internal/gtest-filepath.h>
+#include <gtest/internal/gtest-port.h>
+
+#ifdef _WIN32
+#include <direct.h>
+#include <io.h>
+#endif  // _WIN32
+
+#include <sys/stat.h>
+
+#include <gtest/internal/gtest-string.h>
+
+namespace testing {
+namespace internal {
+
+#ifdef GTEST_OS_WINDOWS
+const char kPathSeparator = '\\';
+const char kPathSeparatorString[] = "\\";
+const char kCurrentDirectoryString[] = ".\\";
+#else
+const char kPathSeparator = '/';
+const char kPathSeparatorString[] = "/";
+const char kCurrentDirectoryString[] = "./";
+#endif  // GTEST_OS_WINDOWS
+
+// Returns a copy of the FilePath with the case-insensitive extension removed.
+// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
+// FilePath("dir/file"). If a case-insensitive extension is not
+// found, returns a copy of the original FilePath.
+FilePath FilePath::RemoveExtension(const char* extension) const {
+  String dot_extension(String::Format(".%s", extension));
+  if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) {
+    return FilePath(String(pathname_.c_str(), pathname_.GetLength() - 4));
+  }
+  return *this;
+}
+
+// Returns a copy of the FilePath with the directory part removed.
+// Example: FilePath("path/to/file").RemoveDirectoryName() returns
+// FilePath("file"). If there is no directory part ("just_a_file"), it returns
+// the FilePath unmodified. If there is no file part ("just_a_dir/") it
+// returns an empty FilePath ("").
+// On Windows platform, '\' is the path separator, otherwise it is '/'.
+FilePath FilePath::RemoveDirectoryName() const {
+  const char* const last_sep = strrchr(c_str(), kPathSeparator);
+  return last_sep ? FilePath(String(last_sep + 1)) : *this;
+}
+
+// RemoveFileName returns the directory path with the filename removed.
+// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
+// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
+// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
+// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
+// On Windows platform, '\' is the path separator, otherwise it is '/'.
+FilePath FilePath::RemoveFileName() const {
+  const char* const last_sep = strrchr(c_str(), kPathSeparator);
+  return FilePath(last_sep ? String(c_str(), last_sep + 1 - c_str())
+                           : String(kCurrentDirectoryString));
+}
+
+// Helper functions for naming files in a directory for xml output.
+
+// Given directory = "dir", base_name = "test", number = 0,
+// extension = "xml", returns "dir/test.xml". If number is greater
+// than zero (e.g., 12), returns "dir/test_12.xml".
+// On Windows platform, uses \ as the separator rather than /.
+FilePath FilePath::MakeFileName(const FilePath& directory,
+                                const FilePath& base_name,
+                                int number,
+                                const char* extension) {
+  FilePath dir(directory.RemoveTrailingPathSeparator());
+  if (number == 0) {
+    return FilePath(String::Format("%s%c%s.%s", dir.c_str(), kPathSeparator,
+                                   base_name.c_str(), extension));
+  }
+  return FilePath(String::Format("%s%c%s_%d.%s", dir.c_str(), kPathSeparator,
+                                 base_name.c_str(), number, extension));
+}
+
+// Returns true if pathname describes something findable in the file-system,
+// either a file, directory, or whatever.
+bool FilePath::FileOrDirectoryExists() const {
+#ifdef GTEST_OS_WINDOWS
+  struct _stat file_stat = {};
+  return _stat(pathname_.c_str(), &file_stat) == 0;
+#else
+  struct stat file_stat = {};
+  return stat(pathname_.c_str(), &file_stat) == 0;
+#endif  // GTEST_OS_WINDOWS
+}
+
+// Returns true if pathname describes a directory in the file-system
+// that exists.
+bool FilePath::DirectoryExists() const {
+  bool result = false;
+#ifdef _WIN32
+  FilePath removed_sep(this->RemoveTrailingPathSeparator());
+  struct _stat file_stat = {};
+  result = _stat(removed_sep.c_str(), &file_stat) == 0 &&
+      (_S_IFDIR & file_stat.st_mode) != 0;
+#else
+  struct stat file_stat = {};
+  result = stat(pathname_.c_str(), &file_stat) == 0 &&
+      S_ISDIR(file_stat.st_mode);
+#endif  // _WIN32
+  return result;
+}
+
+// Returns a pathname for a file that does not currently exist. The pathname
+// will be directory/base_name.extension or
+// directory/base_name_<number>.extension if directory/base_name.extension
+// already exists. The number will be incremented until a pathname is found
+// that does not already exist.
+// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
+// There could be a race condition if two or more processes are calling this
+// function at the same time -- they could both pick the same filename.
+FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
+                                          const FilePath& base_name,
+                                          const char* extension) {
+  FilePath full_pathname;
+  int number = 0;
+  do {
+    full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
+  } while (full_pathname.FileOrDirectoryExists());
+  return full_pathname;
+}
+
+// Returns true if FilePath ends with a path separator, which indicates that
+// it is intended to represent a directory. Returns false otherwise.
+// This does NOT check that a directory (or file) actually exists.
+bool FilePath::IsDirectory() const {
+  return pathname_.EndsWith(kPathSeparatorString);
+}
+
+// Create directories so that path exists. Returns true if successful or if
+// the directories already exist; returns false if unable to create directories
+// for any reason.
+bool FilePath::CreateDirectoriesRecursively() const {
+  if (!this->IsDirectory()) {
+    return false;
+  }
+
+  if (pathname_.GetLength() == 0 || this->DirectoryExists()) {
+    return true;
+  }
+
+  const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
+  return parent.CreateDirectoriesRecursively() && this->CreateFolder();
+}
+
+// Create the directory so that path exists. Returns true if successful or
+// if the directory already exists; returns false if unable to create the
+// directory for any reason, including if the parent directory does not
+// exist. Not named "CreateDirectory" because that's a macro on Windows.
+bool FilePath::CreateFolder() const {
+#ifdef _WIN32
+  int result = _mkdir(pathname_.c_str());
+#else
+  int result = mkdir(pathname_.c_str(), 0777);
+#endif  // _WIN32
+  if (result == -1) {
+    return this->DirectoryExists();  // An error is OK if the directory exists.
+  }
+  return true;  // No error.
+}
+
+// If input name has a trailing separator character, remove it and return the
+// name, otherwise return the name string unmodified.
+// On Windows platform, uses \ as the separator, other platforms use /.
+FilePath FilePath::RemoveTrailingPathSeparator() const {
+  return pathname_.EndsWith(kPathSeparatorString)
+      ? FilePath(String(pathname_.c_str(), pathname_.GetLength() - 1))
+      : *this;
+}
+
+}  // namespace internal
+}  // namespace testing
diff --git a/src/gtest/gtest-internal-inl.h b/src/gtest/gtest-internal-inl.h
new file mode 100644
index 0000000..2a7d71c
--- /dev/null
+++ b/src/gtest/gtest-internal-inl.h
@@ -0,0 +1,1118 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Utility functions and classes used by the Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// This file contains purely Google Test's internal implementation.  Please
+// DO NOT #INCLUDE IT IN A USER PROGRAM.
+
+#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
+#define GTEST_SRC_GTEST_INTERNAL_INL_H_
+
+// GTEST_IMPLEMENTATION is defined iff the current translation unit is
+// part of Google Test's implementation.
+#ifndef GTEST_IMPLEMENTATION
+// A user is trying to include this from his code - just say no.
+#error "gtest-internal-inl.h is part of Google Test's internal implementation."
+#error "It must not be included except by Google Test itself."
+#endif  // GTEST_IMPLEMENTATION
+
+#include <stddef.h>
+
+#include <gtest/internal/gtest-port.h>
+
+#ifdef GTEST_OS_WINDOWS
+#include <windows.h>  // NOLINT
+#endif  // GTEST_OS_WINDOWS
+
+#include <ostream>  // NOLINT
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+namespace testing {
+
+// Declares the flags.
+//
+// We don't want the users to modify these flags in the code, but want
+// Google Test's own unit tests to be able to access them.  Therefore we
+// declare them here as opposed to in gtest.h.
+GTEST_DECLARE_bool(break_on_failure);
+GTEST_DECLARE_bool(catch_exceptions);
+GTEST_DECLARE_string(color);
+GTEST_DECLARE_string(filter);
+GTEST_DECLARE_bool(list_tests);
+GTEST_DECLARE_string(output);
+GTEST_DECLARE_int32(repeat);
+GTEST_DECLARE_int32(stack_trace_depth);
+GTEST_DECLARE_bool(show_internal_stack_frames);
+
+namespace internal {
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kBreakOnFailureFlag[] = "break_on_failure";
+const char kCatchExceptionsFlag[] = "catch_exceptions";
+const char kFilterFlag[] = "filter";
+const char kListTestsFlag[] = "list_tests";
+const char kOutputFlag[] = "output";
+const char kColorFlag[] = "color";
+const char kRepeatFlag[] = "repeat";
+
+// This class saves the values of all Google Test flags in its c'tor, and
+// restores them in its d'tor.
+class GTestFlagSaver {
+ public:
+  // The c'tor.
+  GTestFlagSaver() {
+    break_on_failure_ = GTEST_FLAG(break_on_failure);
+    catch_exceptions_ = GTEST_FLAG(catch_exceptions);
+    color_ = GTEST_FLAG(color);
+    death_test_style_ = GTEST_FLAG(death_test_style);
+    filter_ = GTEST_FLAG(filter);
+    internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
+    list_tests_ = GTEST_FLAG(list_tests);
+    output_ = GTEST_FLAG(output);
+    repeat_ = GTEST_FLAG(repeat);
+  }
+
+  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS.
+  ~GTestFlagSaver() {
+    GTEST_FLAG(break_on_failure) = break_on_failure_;
+    GTEST_FLAG(catch_exceptions) = catch_exceptions_;
+    GTEST_FLAG(color) = color_;
+    GTEST_FLAG(death_test_style) = death_test_style_;
+    GTEST_FLAG(filter) = filter_;
+    GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
+    GTEST_FLAG(list_tests) = list_tests_;
+    GTEST_FLAG(output) = output_;
+    GTEST_FLAG(repeat) = repeat_;
+  }
+ private:
+  // Fields for saving the original values of flags.
+  bool break_on_failure_;
+  bool catch_exceptions_;
+  String color_;
+  String death_test_style_;
+  String filter_;
+  String internal_run_death_test_;
+  bool list_tests_;
+  String output_;
+  bool pretty_;
+  internal::Int32 repeat_;
+} GTEST_ATTRIBUTE_UNUSED;
+
+// Converts a Unicode code-point to its UTF-8 encoding.
+String ToUtf8String(wchar_t wchar);
+
+// Returns the number of active threads, or 0 when there is an error.
+size_t GetThreadCount();
+
+// List is a simple singly-linked list container.
+//
+// We cannot use std::list as Microsoft's implementation of STL has
+// problems when exception is disabled.  There is a hack to work
+// around this, but we've seen cases where the hack fails to work.
+//
+// TODO(wan): switch to std::list when we have a reliable fix for the
+// STL problem, e.g. when we upgrade to the next version of Visual
+// C++, or (more likely) switch to STLport.
+//
+// The element type must support copy constructor.
+
+// Forward declare List
+template <typename E>  // E is the element type.
+class List;
+
+// ListNode is a node in a singly-linked list.  It consists of an
+// element and a pointer to the next node.  The last node in the list
+// has a NULL value for its next pointer.
+template <typename E>  // E is the element type.
+class ListNode {
+  friend class List<E>;
+
+ private:
+
+  E element_;
+  ListNode * next_;
+
+  // The c'tor is private s.t. only in the ListNode class and in its
+  // friend class List we can create a ListNode object.
+  //
+  // Creates a node with a given element value.  The next pointer is
+  // set to NULL.
+  //
+  // ListNode does NOT have a default constructor.  Always use this
+  // constructor (with parameter) to create a ListNode object.
+  explicit ListNode(const E & element) : element_(element), next_(NULL) {}
+
+  // We disallow copying ListNode
+  GTEST_DISALLOW_COPY_AND_ASSIGN(ListNode);
+
+ public:
+
+  // Gets the element in this node.
+  E & element() { return element_; }
+  const E & element() const { return element_; }
+
+  // Gets the next node in the list.
+  ListNode * next() { return next_; }
+  const ListNode * next() const { return next_; }
+};
+
+
+// List is a simple singly-linked list container.
+template <typename E>  // E is the element type.
+class List {
+ public:
+
+  // Creates an empty list.
+  List() : head_(NULL), last_(NULL), size_(0) {}
+
+  // D'tor.
+  virtual ~List();
+
+  // Clears the list.
+  void Clear() {
+    if ( size_ > 0 ) {
+      // 1. Deletes every node.
+      ListNode<E> * node = head_;
+      ListNode<E> * next = node->next();
+      for ( ; ; ) {
+        delete node;
+        node = next;
+        if ( node == NULL ) break;
+        next = node->next();
+      }
+
+      // 2. Resets the member variables.
+      head_ = last_ = NULL;
+      size_ = 0;
+    }
+  }
+
+  // Gets the number of elements.
+  int size() const { return size_; }
+
+  // Returns true if the list is empty.
+  bool IsEmpty() const { return size() == 0; }
+
+  // Gets the first element of the list, or NULL if the list is empty.
+  ListNode<E> * Head() { return head_; }
+  const ListNode<E> * Head() const { return head_; }
+
+  // Gets the last element of the list, or NULL if the list is empty.
+  ListNode<E> * Last() { return last_; }
+  const ListNode<E> * Last() const { return last_; }
+
+  // Adds an element to the end of the list.  A copy of the element is
+  // created using the copy constructor, and then stored in the list.
+  // Changes made to the element in the list doesn't affect the source
+  // object, and vice versa.
+  void PushBack(const E & element) {
+    ListNode<E> * new_node = new ListNode<E>(element);
+
+    if ( size_ == 0 ) {
+      head_ = last_ = new_node;
+      size_ = 1;
+    } else {
+      last_->next_ = new_node;
+      last_ = new_node;
+      size_++;
+    }
+  }
+
+  // Adds an element to the beginning of this list.
+  void PushFront(const E& element) {
+    ListNode<E>* const new_node = new ListNode<E>(element);
+
+    if ( size_ == 0 ) {
+      head_ = last_ = new_node;
+      size_ = 1;
+    } else {
+      new_node->next_ = head_;
+      head_ = new_node;
+      size_++;
+    }
+  }
+
+  // Removes an element from the beginning of this list.  If the
+  // result argument is not NULL, the removed element is stored in the
+  // memory it points to.  Otherwise the element is thrown away.
+  // Returns true iff the list wasn't empty before the operation.
+  bool PopFront(E* result) {
+    if (size_ == 0) return false;
+
+    if (result != NULL) {
+      *result = head_->element_;
+    }
+
+    ListNode<E>* const old_head = head_;
+    size_--;
+    if (size_ == 0) {
+      head_ = last_ = NULL;
+    } else {
+      head_ = head_->next_;
+    }
+    delete old_head;
+
+    return true;
+  }
+
+  // Inserts an element after a given node in the list.  It's the
+  // caller's responsibility to ensure that the given node is in the
+  // list.  If the given node is NULL, inserts the element at the
+  // front of the list.
+  ListNode<E>* InsertAfter(ListNode<E>* node, const E& element) {
+    if (node == NULL) {
+      PushFront(element);
+      return Head();
+    }
+
+    ListNode<E>* const new_node = new ListNode<E>(element);
+    new_node->next_ = node->next_;
+    node->next_ = new_node;
+    size_++;
+    if (node == last_) {
+      last_ = new_node;
+    }
+
+    return new_node;
+  }
+
+  // Returns the number of elements that satisfy a given predicate.
+  // The parameter 'predicate' is a Boolean function or functor that
+  // accepts a 'const E &', where E is the element type.
+  template <typename P>  // P is the type of the predicate function/functor
+  int CountIf(P predicate) const {
+    int count = 0;
+    for ( const ListNode<E> * node = Head();
+          node != NULL;
+          node = node->next() ) {
+      if ( predicate(node->element()) ) {
+        count++;
+      }
+    }
+
+    return count;
+  }
+
+  // Applies a function/functor to each element in the list.  The
+  // parameter 'functor' is a function/functor that accepts a 'const
+  // E &', where E is the element type.  This method does not change
+  // the elements.
+  template <typename F>  // F is the type of the function/functor
+  void ForEach(F functor) const {
+    for ( const ListNode<E> * node = Head();
+          node != NULL;
+          node = node->next() ) {
+      functor(node->element());
+    }
+  }
+
+  // Returns the first node whose element satisfies a given predicate,
+  // or NULL if none is found.  The parameter 'predicate' is a
+  // function/functor that accepts a 'const E &', where E is the
+  // element type.  This method does not change the elements.
+  template <typename P>  // P is the type of the predicate function/functor.
+  const ListNode<E> * FindIf(P predicate) const {
+    for ( const ListNode<E> * node = Head();
+          node != NULL;
+          node = node->next() ) {
+      if ( predicate(node->element()) ) {
+        return node;
+      }
+    }
+
+    return NULL;
+  }
+
+  template <typename P>
+  ListNode<E> * FindIf(P predicate) {
+    for ( ListNode<E> * node = Head();
+          node != NULL;
+          node = node->next() ) {
+      if ( predicate(node->element() ) ) {
+        return node;
+      }
+    }
+
+    return NULL;
+  }
+
+ private:
+  ListNode<E>* head_;  // The first node of the list.
+  ListNode<E>* last_;  // The last node of the list.
+  int size_;           // The number of elements in the list.
+
+  // We disallow copying List.
+  GTEST_DISALLOW_COPY_AND_ASSIGN(List);
+};
+
+// The virtual destructor of List.
+template <typename E>
+List<E>::~List() {
+  Clear();
+}
+
+// A function for deleting an object.  Handy for being used as a
+// functor.
+template <typename T>
+static void Delete(T * x) {
+  delete x;
+}
+
+// A copyable object representing a user specified test property which can be
+// output as a key/value string pair.
+//
+// Don't inherit from TestProperty as its destructor is not virtual.
+class TestProperty {
+ public:
+  // C'tor.  TestProperty does NOT have a default constructor.
+  // Always use this constructor (with parameters) to create a
+  // TestProperty object.
+  TestProperty(const char* key, const char* value) :
+    key_(key), value_(value) {
+  }
+
+  // Gets the user supplied key.
+  const char* key() const {
+    return key_.c_str();
+  }
+
+  // Gets the user supplied value.
+  const char* value() const {
+    return value_.c_str();
+  }
+
+  // Sets a new value, overriding the one supplied in the constructor.
+  void SetValue(const char* new_value) {
+    value_ = new_value;
+  }
+
+ private:
+  // The key supplied by the user.
+  String key_;
+  // The value supplied by the user.
+  String value_;
+};
+
+// A predicate that checks the key of a TestProperty against a known key.
+//
+// TestPropertyKeyIs is copyable.
+class TestPropertyKeyIs {
+ public:
+  // Constructor.
+  //
+  // TestPropertyKeyIs has NO default constructor.
+  explicit TestPropertyKeyIs(const char* key)
+      : key_(key) {}
+
+  // Returns true iff the test name of test property matches on key_.
+  bool operator()(const TestProperty& test_property) const {
+    return String(test_property.key()).Compare(key_) == 0;
+  }
+
+ private:
+  String key_;
+};
+
+// The result of a single Test.  This includes a list of
+// TestPartResults, a list of TestProperties, a count of how many
+// death tests there are in the Test, and how much time it took to run
+// the Test.
+//
+// TestResult is not copyable.
+class TestResult {
+ public:
+  // Creates an empty TestResult.
+  TestResult();
+
+  // D'tor.  Do not inherit from TestResult.
+  ~TestResult();
+
+  // Gets the list of TestPartResults.
+  const internal::List<TestPartResult> & test_part_results() const {
+    return test_part_results_;
+  }
+
+  // Gets the list of TestProperties.
+  const internal::List<internal::TestProperty> & test_properties() const {
+    return test_properties_;
+  }
+
+  // Gets the number of successful test parts.
+  int successful_part_count() const;
+
+  // Gets the number of failed test parts.
+  int failed_part_count() const;
+
+  // Gets the number of all test parts.  This is the sum of the number
+  // of successful test parts and the number of failed test parts.
+  int total_part_count() const;
+
+  // Returns true iff the test passed (i.e. no test part failed).
+  bool Passed() const { return !Failed(); }
+
+  // Returns true iff the test failed.
+  bool Failed() const { return failed_part_count() > 0; }
+
+  // Returns true iff the test fatally failed.
+  bool HasFatalFailure() const;
+
+  // Returns the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Sets the elapsed time.
+  void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
+
+  // Adds a test part result to the list.
+  void AddTestPartResult(const TestPartResult& test_part_result);
+
+  // Adds a test property to the list. The property is validated and may add
+  // a non-fatal failure if invalid (e.g., if it conflicts with reserved
+  // key names). If a property is already recorded for the same key, the
+  // value will be updated, rather than storing multiple values for the same
+  // key.
+  void RecordProperty(const internal::TestProperty& test_property);
+
+  // Adds a failure if the key is a reserved attribute of Google Test
+  // testcase tags.  Returns true if the property is valid.
+  // TODO(russr): Validate attribute names are legal and human readable.
+  static bool ValidateTestProperty(const internal::TestProperty& test_property);
+
+  // Returns the death test count.
+  int death_test_count() const { return death_test_count_; }
+
+  // Increments the death test count, returning the new count.
+  int increment_death_test_count() { return ++death_test_count_; }
+
+  // Clears the object.
+  void Clear();
+ private:
+  // Protects mutable state of the property list and of owned properties, whose
+  // values may be updated.
+  internal::Mutex test_properites_mutex_;
+
+  // The list of TestPartResults
+  internal::List<TestPartResult> test_part_results_;
+  // The list of TestProperties
+  internal::List<internal::TestProperty> test_properties_;
+  // Running count of death tests.
+  int death_test_count_;
+  // The elapsed time, in milliseconds.
+  TimeInMillis elapsed_time_;
+
+  // We disallow copying TestResult.
+  GTEST_DISALLOW_COPY_AND_ASSIGN(TestResult);
+};  // class TestResult
+
+class TestInfoImpl {
+ public:
+  TestInfoImpl(TestInfo* parent, const char* test_case_name,
+               const char* name, TypeId fixture_class_id,
+               TestMaker maker);
+  ~TestInfoImpl();
+
+  // Returns true if this test should run.
+  bool should_run() const { return should_run_; }
+
+  // Sets the should_run member.
+  void set_should_run(bool should) { should_run_ = should; }
+
+  // Returns true if this test is disabled. Disabled tests are not run.
+  bool is_disabled() const { return is_disabled_; }
+
+  // Sets the is_disabled member.
+  void set_is_disabled(bool is) { is_disabled_ = is; }
+
+  // Returns the test case name.
+  const char* test_case_name() const { return test_case_name_.c_str(); }
+
+  // Returns the test name.
+  const char* name() const { return name_.c_str(); }
+
+  // Returns the ID of the test fixture class.
+  TypeId fixture_class_id() const { return fixture_class_id_; }
+
+  // Returns the test result.
+  internal::TestResult* result() { return &result_; }
+  const internal::TestResult* result() const { return &result_; }
+
+  // Creates the test object, runs it, records its result, and then
+  // deletes it.
+  void Run();
+
+  // Calls the given TestInfo object's Run() method.
+  static void RunTest(TestInfo * test_info) {
+    test_info->impl()->Run();
+  }
+
+  // Clears the test result.
+  void ClearResult() { result_.Clear(); }
+
+  // Clears the test result in the given TestInfo object.
+  static void ClearTestResult(TestInfo * test_info) {
+    test_info->impl()->ClearResult();
+  }
+
+ private:
+  // These fields are immutable properties of the test.
+  TestInfo* const parent_;         // The owner of this object
+  const String test_case_name_;    // Test case name
+  const String name_;              // Test name
+  const TypeId fixture_class_id_;  // ID of the test fixture class
+  bool should_run_;                // True iff this test should run
+  bool is_disabled_;               // True iff this test is disabled
+  const TestMaker maker_;          // The function that creates the test object
+
+  // This field is mutable and needs to be reset before running the
+  // test for the second time.
+  internal::TestResult result_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(TestInfoImpl);
+};
+
+}  // namespace internal
+
+// A test case, which consists of a list of TestInfos.
+//
+// TestCase is not copyable.
+class TestCase {
+ public:
+  // Creates a TestCase with the given name.
+  //
+  // TestCase does NOT have a default constructor.  Always use this
+  // constructor to create a TestCase object.
+  //
+  // Arguments:
+  //
+  //   name:         name of the test case
+  //   set_up_tc:    pointer to the function that sets up the test case
+  //   tear_down_tc: pointer to the function that tears down the test case
+  TestCase(const char* name,
+           Test::SetUpTestCaseFunc set_up_tc,
+           Test::TearDownTestCaseFunc tear_down_tc);
+
+  // Destructor of TestCase.
+  virtual ~TestCase();
+
+  // Gets the name of the TestCase.
+  const char* name() const { return name_.c_str(); }
+
+  // Returns true if any test in this test case should run.
+  bool should_run() const { return should_run_; }
+
+  // Sets the should_run member.
+  void set_should_run(bool should) { should_run_ = should; }
+
+  // Gets the (mutable) list of TestInfos in this TestCase.
+  internal::List<TestInfo*>& test_info_list() { return *test_info_list_; }
+
+  // Gets the (immutable) list of TestInfos in this TestCase.
+  const internal::List<TestInfo *> & test_info_list() const {
+    return *test_info_list_;
+  }
+
+  // Gets the number of successful tests in this test case.
+  int successful_test_count() const;
+
+  // Gets the number of failed tests in this test case.
+  int failed_test_count() const;
+
+  // Gets the number of disabled tests in this test case.
+  int disabled_test_count() const;
+
+  // Get the number of tests in this test case that should run.
+  int test_to_run_count() const;
+
+  // Gets the number of all tests in this test case.
+  int total_test_count() const;
+
+  // Returns true iff the test case passed.
+  bool Passed() const { return !Failed(); }
+
+  // Returns true iff the test case failed.
+  bool Failed() const { return failed_test_count() > 0; }
+
+  // Returns the elapsed time, in milliseconds.
+  internal::TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Adds a TestInfo to this test case.  Will delete the TestInfo upon
+  // destruction of the TestCase object.
+  void AddTestInfo(TestInfo * test_info);
+
+  // Finds and returns a TestInfo with the given name.  If one doesn't
+  // exist, returns NULL.
+  TestInfo* GetTestInfo(const char* test_name);
+
+  // Clears the results of all tests in this test case.
+  void ClearResult();
+
+  // Clears the results of all tests in the given test case.
+  static void ClearTestCaseResult(TestCase* test_case) {
+    test_case->ClearResult();
+  }
+
+  // Runs every test in this TestCase.
+  void Run();
+
+  // Runs every test in the given TestCase.
+  static void RunTestCase(TestCase * test_case) { test_case->Run(); }
+
+  // Returns true iff test passed.
+  static bool TestPassed(const TestInfo * test_info) {
+    const internal::TestInfoImpl* const impl = test_info->impl();
+    return impl->should_run() && impl->result()->Passed();
+  }
+
+  // Returns true iff test failed.
+  static bool TestFailed(const TestInfo * test_info) {
+    const internal::TestInfoImpl* const impl = test_info->impl();
+    return impl->should_run() && impl->result()->Failed();
+  }
+
+  // Returns true iff test is disabled.
+  static bool TestDisabled(const TestInfo * test_info) {
+    return test_info->impl()->is_disabled();
+  }
+
+  // Returns true if the given test should run.
+  static bool ShouldRunTest(const TestInfo *test_info) {
+    return test_info->impl()->should_run();
+  }
+
+ private:
+  // Name of the test case.
+  internal::String name_;
+  // List of TestInfos.
+  internal::List<TestInfo*>* test_info_list_;
+  // Pointer to the function that sets up the test case.
+  Test::SetUpTestCaseFunc set_up_tc_;
+  // Pointer to the function that tears down the test case.
+  Test::TearDownTestCaseFunc tear_down_tc_;
+  // True iff any test in this test case should run.
+  bool should_run_;
+  // Elapsed time, in milliseconds.
+  internal::TimeInMillis elapsed_time_;
+
+  // We disallow copying TestCases.
+  GTEST_DISALLOW_COPY_AND_ASSIGN(TestCase);
+};
+
+namespace internal {
+
+// Class UnitTestOptions.
+//
+// This class contains functions for processing options the user
+// specifies when running the tests.  It has only static members.
+//
+// In most cases, the user can specify an option using either an
+// environment variable or a command line flag.  E.g. you can set the
+// test filter using either GTEST_FILTER or --gtest_filter.  If both
+// the variable and the flag are present, the latter overrides the
+// former.
+class UnitTestOptions {
+ public:
+  // Functions for processing the gtest_output flag.
+
+  // Returns the output format, or "" for normal printed output.
+  static String GetOutputFormat();
+
+  // Returns the name of the requested output file, or the default if none
+  // was explicitly specified.
+  static String GetOutputFile();
+
+  // Functions for processing the gtest_filter flag.
+
+  // Returns true iff the wildcard pattern matches the string.  The
+  // first ':' or '\0' character in pattern marks the end of it.
+  //
+  // This recursive algorithm isn't very efficient, but is clear and
+  // works well enough for matching test names, which are short.
+  static bool PatternMatchesString(const char *pattern, const char *str);
+
+  // Returns true iff the user-specified filter matches the test case
+  // name and the test name.
+  static bool FilterMatchesTest(const String &test_case_name,
+                                const String &test_name);
+
+#ifdef GTEST_OS_WINDOWS
+  // Function for supporting the gtest_catch_exception flag.
+
+  // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
+  // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
+  // This function is useful as an __except condition.
+  static int GTestShouldProcessSEH(DWORD exception_code);
+#endif  // GTEST_OS_WINDOWS
+ private:
+  // Returns true if "name" matches the ':' separated list of glob-style
+  // filters in "filter".
+  static bool MatchesFilter(const String& name, const char* filter);
+};
+
+// Returns the current application's name, removing directory path if that
+// is present.  Used by UnitTestOptions::GetOutputFile.
+FilePath GetCurrentExecutableName();
+
+// The role interface for getting the OS stack trace as a string.
+class OsStackTraceGetterInterface {
+ public:
+  OsStackTraceGetterInterface() {}
+  virtual ~OsStackTraceGetterInterface() {}
+
+  // Returns the current OS stack trace as a String.  Parameters:
+  //
+  //   max_depth  - the maximum number of stack frames to be included
+  //                in the trace.
+  //   skip_count - the number of top frames to be skipped; doesn't count
+  //                against max_depth.
+  virtual String CurrentStackTrace(int max_depth, int skip_count) = 0;
+
+  // UponLeavingGTest() should be called immediately before Google Test calls
+  // user code. It saves some information about the current stack that
+  // CurrentStackTrace() will use to find and hide Google Test stack frames.
+  virtual void UponLeavingGTest() = 0;
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN(OsStackTraceGetterInterface);
+};
+
+// A working implemenation of the OsStackTraceGetterInterface interface.
+class OsStackTraceGetter : public OsStackTraceGetterInterface {
+ public:
+  OsStackTraceGetter() {}
+  virtual String CurrentStackTrace(int max_depth, int skip_count);
+  virtual void UponLeavingGTest();
+
+  // This string is inserted in place of stack frames that are part of
+  // Google Test's implementation.
+  static const char* const kElidedFramesMarker;
+
+ private:
+  Mutex mutex_;  // protects all internal state
+
+  // We save the stack frame below the frame that calls user code.
+  // We do this because the address of the frame immediately below
+  // the user code changes between the call to UponLeavingGTest()
+  // and any calls to CurrentStackTrace() from within the user code.
+  void* caller_frame_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(OsStackTraceGetter);
+};
+
+// Information about a Google Test trace point.
+struct TraceInfo {
+  const char* file;
+  int line;
+  String message;
+};
+
+// The private implementation of the UnitTest class.  We don't protect
+// the methods under a mutex, as this class is not accessible by a
+// user and the UnitTest class that delegates work to this class does
+// proper locking.
+class UnitTestImpl : public TestPartResultReporterInterface {
+ public:
+  explicit UnitTestImpl(UnitTest* parent);
+  virtual ~UnitTestImpl();
+
+  // Reports a test part result.  This method is from the
+  // TestPartResultReporterInterface interface.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+
+  // Returns the current test part result reporter.
+  TestPartResultReporterInterface* test_part_result_reporter();
+
+  // Sets the current test part result reporter.
+  void set_test_part_result_reporter(TestPartResultReporterInterface* reporter);
+
+  // Gets the number of successful test cases.
+  int successful_test_case_count() const;
+
+  // Gets the number of failed test cases.
+  int failed_test_case_count() const;
+
+  // Gets the number of all test cases.
+  int total_test_case_count() const;
+
+  // Gets the number of all test cases that contain at least one test
+  // that should run.
+  int test_case_to_run_count() const;
+
+  // Gets the number of successful tests.
+  int successful_test_count() const;
+
+  // Gets the number of failed tests.
+  int failed_test_count() const;
+
+  // Gets the number of disabled tests.
+  int disabled_test_count() const;
+
+  // Gets the number of all tests.
+  int total_test_count() const;
+
+  // Gets the number of tests that should run.
+  int test_to_run_count() const;
+
+  // Gets the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns true iff the unit test passed (i.e. all test cases passed).
+  bool Passed() const { return !Failed(); }
+
+  // Returns true iff the unit test failed (i.e. some test case failed
+  // or something outside of all tests failed).
+  bool Failed() const {
+    return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();
+  }
+
+  // Returns the TestResult for the test that's currently running, or
+  // the TestResult for the ad hoc test if no test is running.
+  internal::TestResult* current_test_result();
+
+  // Returns the TestResult for the ad hoc test.
+  const internal::TestResult* ad_hoc_test_result() const {
+    return &ad_hoc_test_result_;
+  }
+
+  // Sets the unit test result printer.
+  //
+  // Does nothing if the input and the current printer object are the
+  // same; otherwise, deletes the old printer object and makes the
+  // input the current printer.
+  void set_result_printer(UnitTestEventListenerInterface * result_printer);
+
+  // Returns the current unit test result printer if it is not NULL;
+  // otherwise, creates an appropriate result printer, makes it the
+  // current printer, and returns it.
+  UnitTestEventListenerInterface* result_printer();
+
+  // Sets the OS stack trace getter.
+  //
+  // Does nothing if the input and the current OS stack trace getter
+  // are the same; otherwise, deletes the old getter and makes the
+  // input the current getter.
+  void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter);
+
+  // Returns the current OS stack trace getter if it is not NULL;
+  // otherwise, creates an OsStackTraceGetter, makes it the current
+  // getter, and returns it.
+  OsStackTraceGetterInterface* os_stack_trace_getter();
+
+  // Returns the current OS stack trace as a String.
+  //
+  // The maximum number of stack frames to be included is specified by
+  // the gtest_stack_trace_depth flag.  The skip_count parameter
+  // specifies the number of top frames to be skipped, which doesn't
+  // count against the number of frames to be included.
+  //
+  // For example, if Foo() calls Bar(), which in turn calls
+  // CurrentOsStackTraceExceptTop(1), Foo() will be included in the
+  // trace but Bar() and CurrentOsStackTraceExceptTop() won't.
+  String CurrentOsStackTraceExceptTop(int skip_count);
+
+  // Finds and returns a TestCase with the given name.  If one doesn't
+  // exist, creates one and returns it.
+  //
+  // Arguments:
+  //
+  //   test_case_name: name of the test case
+  //   set_up_tc:      pointer to the function that sets up the test case
+  //   tear_down_tc:   pointer to the function that tears down the test case
+  TestCase* GetTestCase(const char* test_case_name,
+                        Test::SetUpTestCaseFunc set_up_tc,
+                        Test::TearDownTestCaseFunc tear_down_tc);
+
+  // Adds a TestInfo to the unit test.
+  //
+  // Arguments:
+  //
+  //   set_up_tc:    pointer to the function that sets up the test case
+  //   tear_down_tc: pointer to the function that tears down the test case
+  //   test_info:    the TestInfo object
+  void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
+                   Test::TearDownTestCaseFunc tear_down_tc,
+                   TestInfo * test_info) {
+    GetTestCase(test_info->test_case_name(),
+                set_up_tc,
+                tear_down_tc)->AddTestInfo(test_info);
+  }
+
+  // Sets the TestCase object for the test that's currently running.
+  void set_current_test_case(TestCase* current_test_case) {
+    current_test_case_ = current_test_case;
+  }
+
+  // Sets the TestInfo object for the test that's currently running.  If
+  // current_test_info is NULL, the assertion results will be stored in
+  // ad_hoc_test_result_.
+  void set_current_test_info(TestInfo* current_test_info) {
+    current_test_info_ = current_test_info;
+  }
+
+  // Runs all tests in this UnitTest object, prints the result, and
+  // returns 0 if all tests are successful, or 1 otherwise.  If any
+  // exception is thrown during a test on Windows, this test is
+  // considered to be failed, but the rest of the tests will still be
+  // run.  (We disable exceptions on Linux and Mac OS X, so the issue
+  // doesn't apply there.)
+  int RunAllTests();
+
+  // Clears the results of all tests, including the ad hoc test.
+  void ClearResult() {
+    test_cases_.ForEach(TestCase::ClearTestCaseResult);
+    ad_hoc_test_result_.Clear();
+  }
+
+  // Matches the full name of each test against the user-specified
+  // filter to decide whether the test should run, then records the
+  // result in each TestCase and TestInfo object.
+  // Returns the number of tests that should run.
+  int FilterTests();
+
+  // Lists all the tests by name.
+  void ListAllTests();
+
+  const TestCase* current_test_case() const { return current_test_case_; }
+  TestInfo* current_test_info() { return current_test_info_; }
+  const TestInfo* current_test_info() const { return current_test_info_; }
+
+  // Returns the list of environments that need to be set-up/torn-down
+  // before/after the tests are run.
+  internal::List<Environment*>* environments() { return &environments_; }
+  internal::List<Environment*>* environments_in_reverse_order() {
+    return &environments_in_reverse_order_;
+  }
+
+  internal::List<TestCase*>* test_cases() { return &test_cases_; }
+  const internal::List<TestCase*>* test_cases() const { return &test_cases_; }
+
+  // Getters for the per-thread Google Test trace stack.
+  internal::List<TraceInfo>* gtest_trace_stack() {
+    return gtest_trace_stack_.pointer();
+  }
+  const internal::List<TraceInfo>* gtest_trace_stack() const {
+    return gtest_trace_stack_.pointer();
+  }
+
+#ifdef GTEST_HAS_DEATH_TEST
+  // Returns a pointer to the parsed --gtest_internal_run_death_test
+  // flag, or NULL if that flag was not specified.
+  // This information is useful only in a death test child process.
+  const InternalRunDeathTestFlag* internal_run_death_test_flag() const {
+    return internal_run_death_test_flag_.get();
+  }
+
+  // Returns a pointer to the current death test factory.
+  internal::DeathTestFactory* death_test_factory() {
+    return death_test_factory_.get();
+  }
+
+  friend class ReplaceDeathTestFactory;
+#endif  // GTEST_HAS_DEATH_TEST
+
+ private:
+  // The UnitTest object that owns this implementation object.
+  UnitTest* const parent_;
+
+  // Points to (but doesn't own) the test part result reporter.
+  TestPartResultReporterInterface* test_part_result_reporter_;
+
+  // The list of environments that need to be set-up/torn-down
+  // before/after the tests are run.  environments_in_reverse_order_
+  // simply mirrors environments_ in reverse order.
+  internal::List<Environment*> environments_;
+  internal::List<Environment*> environments_in_reverse_order_;
+
+  internal::List<TestCase*> test_cases_;  // The list of TestCases.
+
+  // Points to the last death test case registered.  Initially NULL.
+  internal::ListNode<TestCase*>* last_death_test_case_;
+
+  // This points to the TestCase for the currently running test.  It
+  // changes as Google Test goes through one test case after another.
+  // When no test is running, this is set to NULL and Google Test
+  // stores assertion results in ad_hoc_test_result_.  Initally NULL.
+  TestCase* current_test_case_;
+
+  // This points to the TestInfo for the currently running test.  It
+  // changes as Google Test goes through one test after another.  When
+  // no test is running, this is set to NULL and Google Test stores
+  // assertion results in ad_hoc_test_result_.  Initially NULL.
+  TestInfo* current_test_info_;
+
+  // Normally, a user only writes assertions inside a TEST or TEST_F,
+  // or inside a function called by a TEST or TEST_F.  Since Google
+  // Test keeps track of which test is current running, it can
+  // associate such an assertion with the test it belongs to.
+  //
+  // If an assertion is encountered when no TEST or TEST_F is running,
+  // Google Test attributes the assertion result to an imaginary "ad hoc"
+  // test, and records the result in ad_hoc_test_result_.
+  internal::TestResult ad_hoc_test_result_;
+
+  // The unit test result printer.  Will be deleted when the UnitTest
+  // object is destructed.  By default, a plain text printer is used,
+  // but the user can set this field to use a custom printer if that
+  // is desired.
+  UnitTestEventListenerInterface* result_printer_;
+
+  // The OS stack trace getter.  Will be deleted when the UnitTest
+  // object is destructed.  By default, an OsStackTraceGetter is used,
+  // but the user can set this field to use a custom getter if that is
+  // desired.
+  OsStackTraceGetterInterface* os_stack_trace_getter_;
+
+  // How long the test took to run, in milliseconds.
+  TimeInMillis elapsed_time_;
+
+#ifdef GTEST_HAS_DEATH_TEST
+  // The decomposed components of the gtest_internal_run_death_test flag,
+  // parsed when RUN_ALL_TESTS is called.
+  internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
+  internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_;
+#endif  // GTEST_HAS_DEATH_TEST
+
+  // A per-thread stack of traces created by the SCOPED_TRACE() macro.
+  internal::ThreadLocal<internal::List<TraceInfo> > gtest_trace_stack_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(UnitTestImpl);
+};  // class UnitTestImpl
+
+// Convenience function for accessing the global UnitTest
+// implementation object.
+inline UnitTestImpl* GetUnitTestImpl() {
+  return UnitTest::GetInstance()->impl();
+}
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_SRC_GTEST_INTERNAL_INL_H_
diff --git a/src/gtest/gtest-message.h b/src/gtest/gtest-message.h
new file mode 100644
index 0000000..746a168
--- /dev/null
+++ b/src/gtest/gtest-message.h
@@ -0,0 +1,236 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the Message class.
+//
+// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
+// leave some internal implementation details in this header file.
+// They are clearly marked by comments like this:
+//
+//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+//
+// Such code is NOT meant to be used by a user directly, and is subject
+// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user
+// program!
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
+
+#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+// When using Google Test on the Mac as a framework, all the includes will be
+// in the framework headers folder along with gtest.h.
+// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on
+// the Mac and are not using it as a framework.
+// More info on frameworks available here:
+// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/
+// Concepts/WhatAreFrameworks.html.
+#include "gtest-string.h"  // NOLINT
+#include "gtest-internal.h"  // NOLINT
+#else
+#include <gtest/internal/gtest-string.h>
+#include <gtest/internal/gtest-internal.h>
+#endif  // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+
+namespace testing {
+
+// The Message class works like an ostream repeater.
+//
+// Typical usage:
+//
+//   1. You stream a bunch of values to a Message object.
+//      It will remember the text in a StrStream.
+//   2. Then you stream the Message object to an ostream.
+//      This causes the text in the Message to be streamed
+//      to the ostream.
+//
+// For example;
+//
+//   testing::Message foo;
+//   foo << 1 << " != " << 2;
+//   std::cout << foo;
+//
+// will print "1 != 2".
+//
+// Message is not intended to be inherited from.  In particular, its
+// destructor is not virtual.
+//
+// Note that StrStream behaves differently in gcc and in MSVC.  You
+// can stream a NULL char pointer to it in the former, but not in the
+// latter (it causes an access violation if you do).  The Message
+// class hides this difference by treating a NULL char pointer as
+// "(null)".
+class Message {
+ private:
+  // The type of basic IO manipulators (endl, ends, and flush) for
+  // narrow streams.
+  typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
+
+ public:
+  // Constructs an empty Message.
+  // We allocate the StrStream separately because it otherwise each use of
+  // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's
+  // stack frame leading to huge stack frames in some cases; gcc does not reuse
+  // the stack space.
+  Message() : ss_(new internal::StrStream) {}
+
+  // Copy constructor.
+  Message(const Message& msg) : ss_(new internal::StrStream) {  // NOLINT
+    *ss_ << msg.GetString();
+  }
+
+  // Constructs a Message from a C-string.
+  explicit Message(const char* str) : ss_(new internal::StrStream) {
+    *ss_ << str;
+  }
+
+  ~Message() { delete ss_; }
+#ifdef __SYMBIAN32__
+  // Streams a value (either a pointer or not) to this object.
+  template <typename T>
+  inline Message& operator <<(const T& value) {
+    StreamHelper(typename internal::is_pointer<T>::type(), value);
+    return *this;
+  }
+#else
+  // Streams a non-pointer value to this object.
+  template <typename T>
+  inline Message& operator <<(const T& val) {
+    ::GTestStreamToHelper(ss_, val);
+    return *this;
+  }
+
+  // Streams a pointer value to this object.
+  //
+  // This function is an overload of the previous one.  When you
+  // stream a pointer to a Message, this definition will be used as it
+  // is more specialized.  (The C++ Standard, section
+  // [temp.func.order].)  If you stream a non-pointer, then the
+  // previous definition will be used.
+  //
+  // The reason for this overload is that streaming a NULL pointer to
+  // ostream is undefined behavior.  Depending on the compiler, you
+  // may get "0", "(nil)", "(null)", or an access violation.  To
+  // ensure consistent result across compilers, we always treat NULL
+  // as "(null)".
+  template <typename T>
+  inline Message& operator <<(T* const& pointer) {  // NOLINT
+    if (pointer == NULL) {
+      *ss_ << "(null)";
+    } else {
+      ::GTestStreamToHelper(ss_, pointer);
+    }
+    return *this;
+  }
+#endif  // __SYMBIAN32__
+
+  // Since the basic IO manipulators are overloaded for both narrow
+  // and wide streams, we have to provide this specialized definition
+  // of operator <<, even though its body is the same as the
+  // templatized version above.  Without this definition, streaming
+  // endl or other basic IO manipulators to Message will confuse the
+  // compiler.
+  Message& operator <<(BasicNarrowIoManip val) {
+    *ss_ << val;
+    return *this;
+  }
+
+  // Instead of 1/0, we want to see true/false for bool values.
+  Message& operator <<(bool b) {
+    return *this << (b ? "true" : "false");
+  }
+
+  // These two overloads allow streaming a wide C string to a Message
+  // using the UTF-8 encoding.
+  Message& operator <<(const wchar_t* wide_c_str) {
+    return *this << internal::String::ShowWideCString(wide_c_str);
+  }
+  Message& operator <<(wchar_t* wide_c_str) {
+    return *this << internal::String::ShowWideCString(wide_c_str);
+  }
+
+#if GTEST_HAS_STD_WSTRING
+  // Converts the given wide string to a narrow string using the UTF-8
+  // encoding, and streams the result to this Message object.
+  Message& operator <<(const ::std::wstring& wstr);
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+  // Converts the given wide string to a narrow string using the UTF-8
+  // encoding, and streams the result to this Message object.
+  Message& operator <<(const ::wstring& wstr);
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+  // Gets the text streamed to this object so far as a String.
+  // Each '\0' character in the buffer is replaced with "\\0".
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  internal::String GetString() const {
+    return internal::StrStreamToString(ss_);
+  }
+
+ private:
+#ifdef __SYMBIAN32__
+  // These are needed as the Nokia Symbian Compiler cannot decide between
+  // const T& and const T* in a function template. The Nokia compiler _can_
+  // decide between class template specializations for T and T*, so a
+  // tr1::type_traits-like is_pointer works, and we can overload on that.
+  template <typename T>
+  inline void StreamHelper(internal::true_type dummy, T* pointer) {
+    if (pointer == NULL) {
+      *ss_ << "(null)";
+    } else {
+      ::GTestStreamToHelper(ss_, pointer);
+    }
+  }
+  template <typename T>
+  inline void StreamHelper(internal::false_type dummy, const T& value) {
+    ::GTestStreamToHelper(ss_, value);
+  }
+#endif  // __SYMBIAN32__
+
+  // We'll hold the text streamed to this object here.
+  internal::StrStream* const ss_;
+
+  // We declare (but don't implement) this to prevent the compiler
+  // from implementing the assignment operator.
+  void operator=(const Message&);
+};
+
+// Streams a Message to an ostream.
+inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
+  return os << sb.GetString();
+}
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
diff --git a/src/gtest/gtest-port.cc b/src/gtest/gtest-port.cc
new file mode 100644
index 0000000..5c12614
--- /dev/null
+++ b/src/gtest/gtest-port.cc
@@ -0,0 +1,292 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#include <gtest/internal/gtest-port.h>
+
+#include <limits.h>
+#ifdef GTEST_HAS_DEATH_TEST
+#include <regex.h>
+#endif  // GTEST_HAS_DEATH_TEST
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <gtest/gtest-spi.h>
+#include <gtest/gtest-message.h>
+#include <gtest/internal/gtest-string.h>
+
+namespace testing {
+namespace internal {
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// Implements RE.  Currently only needed for death tests.
+
+RE::~RE() {
+  regfree(&regex_);
+  free(const_cast<char*>(pattern_));
+}
+
+// Returns true iff str contains regular expression re.
+bool RE::PartialMatch(const char* str, const RE& re) {
+  if (!re.is_valid_) return false;
+
+  regmatch_t match;
+  return regexec(&re.regex_, str, 1, &match, 0) == 0;
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+  pattern_ = strdup(regex);
+  is_valid_ = regcomp(&regex_, regex, REG_EXTENDED) == 0;
+  EXPECT_TRUE(is_valid_)
+      << "Regular expression \"" << regex
+      << "\" is not a valid POSIX Extended regular expression.";
+}
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Logs a message at the given severity level.
+void GTestLog(GTestLogSeverity severity, const char* file,
+              int line, const char* msg) {
+  const char* const marker =
+      severity == GTEST_INFO ?    "[  INFO ]" :
+      severity == GTEST_WARNING ? "[WARNING]" :
+      severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]";
+  fprintf(stderr, "\n%s %s:%d: %s\n", marker, file, line, msg);
+  if (severity == GTEST_FATAL) {
+    abort();
+  }
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// Defines the stderr capturer.
+
+class CapturedStderr {
+ public:
+  // The ctor redirects stderr to a temporary file.
+  CapturedStderr() {
+    uncaptured_fd_ = dup(STDERR_FILENO);
+
+    char name_template[] = "captured_stderr.XXXXXX";
+    const int captured_fd = mkstemp(name_template);
+    filename_ = name_template;
+    fflush(NULL);
+    dup2(captured_fd, STDERR_FILENO);
+    close(captured_fd);
+  }
+
+  ~CapturedStderr() {
+    remove(filename_.c_str());
+  }
+
+  // Stops redirecting stderr.
+  void StopCapture() {
+    // Restores the original stream.
+    fflush(NULL);
+    dup2(uncaptured_fd_, STDERR_FILENO);
+    close(uncaptured_fd_);
+    uncaptured_fd_ = -1;
+  }
+
+  // Returns the name of the temporary file holding the stderr output.
+  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
+  // can use it here.
+  ::std::string filename() const { return filename_; }
+
+ private:
+  int uncaptured_fd_;
+  ::std::string filename_;
+};
+
+static CapturedStderr* g_captured_stderr = NULL;
+
+// Returns the size (in bytes) of a file.
+static size_t GetFileSize(FILE * file) {
+  fseek(file, 0, SEEK_END);
+  return static_cast<size_t>(ftell(file));
+}
+
+// Reads the entire content of a file as a string.
+// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can
+// use it here.
+static ::std::string ReadEntireFile(FILE * file) {
+  const size_t file_size = GetFileSize(file);
+  char* const buffer = new char[file_size];
+
+  size_t bytes_last_read = 0;  // # of bytes read in the last fread()
+  size_t bytes_read = 0;       // # of bytes read so far
+
+  fseek(file, 0, SEEK_SET);
+
+  // Keeps reading the file until we cannot read further or the
+  // pre-determined file size is reached.
+  do {
+    bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
+    bytes_read += bytes_last_read;
+  } while (bytes_last_read > 0 && bytes_read < file_size);
+
+  const ::std::string content(buffer, buffer+bytes_read);
+  delete[] buffer;
+
+  return content;
+}
+
+// Starts capturing stderr.
+void CaptureStderr() {
+  if (g_captured_stderr != NULL) {
+    GTEST_LOG(FATAL, "Only one stderr capturer can exist at one time.");
+  }
+  g_captured_stderr = new CapturedStderr;
+}
+
+// Stops capturing stderr and returns the captured string.
+// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can
+// use it here.
+::std::string GetCapturedStderr() {
+  g_captured_stderr->StopCapture();
+  FILE* const file = fopen(g_captured_stderr->filename().c_str(), "r");
+  const ::std::string content = ReadEntireFile(file);
+  fclose(file);
+
+  delete g_captured_stderr;
+  g_captured_stderr = NULL;
+
+  return content;
+}
+
+// A copy of all command line arguments.  Set by ParseGTestFlags().
+::std::vector<String> g_argvs;
+
+// Returns the command line as a vector of strings.
+const ::std::vector<String>& GetArgvs() { return g_argvs; }
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Returns the name of the environment variable corresponding to the
+// given flag.  For example, FlagToEnvVar("foo") will return
+// "GTEST_FOO" in the open-source version.
+static String FlagToEnvVar(const char* flag) {
+  const String full_flag = (Message() << GTEST_FLAG_PREFIX << flag).GetString();
+
+  Message env_var;
+  for (int i = 0; i != full_flag.GetLength(); i++) {
+    env_var << static_cast<char>(toupper(full_flag.c_str()[i]));
+  }
+
+  return env_var.GetString();
+}
+
+// Reads and returns the Boolean environment variable corresponding to
+// the given flag; if it's not set, returns default_value.
+//
+// The value is considered true iff it's not "0".
+bool BoolFromGTestEnv(const char* flag, bool default_value) {
+  const String env_var = FlagToEnvVar(flag);
+  const char* const string_value = GetEnv(env_var.c_str());
+  return string_value == NULL ?
+      default_value : strcmp(string_value, "0") != 0;
+}
+
+// Parses 'str' for a 32-bit signed integer.  If successful, writes
+// the result to *value and returns true; otherwise leaves *value
+// unchanged and returns false.
+bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
+  // Parses the environment variable as a decimal integer.
+  char* end = NULL;
+  const long long_value = strtol(str, &end, 10);  // NOLINT
+
+  // Has strtol() consumed all characters in the string?
+  if (*end != '\0') {
+    // No - an invalid character was encountered.
+    Message msg;
+    msg << "WARNING: " << src_text
+        << " is expected to be a 32-bit integer, but actually"
+        << " has value \"" << str << "\".\n";
+    printf("%s", msg.GetString().c_str());
+    fflush(stdout);
+    return false;
+  }
+
+  // Is the parsed value in the range of an Int32?
+  const Int32 result = static_cast<Int32>(long_value);
+  if (long_value == LONG_MAX || long_value == LONG_MIN ||
+      // The parsed value overflows as a long.  (strtol() returns
+      // LONG_MAX or LONG_MIN when the input overflows.)
+      result != long_value
+      // The parsed value overflows as an Int32.
+      ) {
+    Message msg;
+    msg << "WARNING: " << src_text
+        << " is expected to be a 32-bit integer, but actually"
+        << " has value " << str << ", which overflows.\n";
+    printf("%s", msg.GetString().c_str());
+    fflush(stdout);
+    return false;
+  }
+
+  *value = result;
+  return true;
+}
+
+// Reads and returns a 32-bit integer stored in the environment
+// variable corresponding to the given flag; if it isn't set or
+// doesn't represent a valid 32-bit integer, returns default_value.
+Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
+  const String env_var = FlagToEnvVar(flag);
+  const char* const string_value = GetEnv(env_var.c_str());
+  if (string_value == NULL) {
+    // The environment variable is not set.
+    return default_value;
+  }
+
+  Int32 result = default_value;
+  if (!ParseInt32(Message() << "Environment variable " << env_var,
+                  string_value, &result)) {
+    printf("The default value %s is used.\n",
+           (Message() << default_value).GetString().c_str());
+    fflush(stdout);
+    return default_value;
+  }
+
+  return result;
+}
+
+// Reads and returns the string environment variable corresponding to
+// the given flag; if it's not set, returns default_value.
+const char* StringFromGTestEnv(const char* flag, const char* default_value) {
+  const String env_var = FlagToEnvVar(flag);
+  const char* const value = GetEnv(env_var.c_str());
+  return value == NULL ? default_value : value;
+}
+
+}  // namespace internal
+}  // namespace testing
diff --git a/src/gtest/gtest-spi.h b/src/gtest/gtest-spi.h
new file mode 100644
index 0000000..75d0dcf
--- /dev/null
+++ b/src/gtest/gtest-spi.h
@@ -0,0 +1,247 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// Utilities for testing Google Test itself and code that uses Google Test
+// (e.g. frameworks built on top of Google Test).
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+
+#include <gtest/gtest.h>
+
+namespace testing {
+
+// A copyable object representing the result of a test part (i.e. an
+// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
+//
+// Don't inherit from TestPartResult as its destructor is not virtual.
+class TestPartResult {
+ public:
+  // C'tor.  TestPartResult does NOT have a default constructor.
+  // Always use this constructor (with parameters) to create a
+  // TestPartResult object.
+  TestPartResult(TestPartResultType type,
+                 const char* file_name,
+                 int line_number,
+                 const char* message)
+      : type_(type),
+        file_name_(file_name),
+        line_number_(line_number),
+        message_(message) {
+  }
+
+  // Gets the outcome of the test part.
+  TestPartResultType type() const { return type_; }
+
+  // Gets the name of the source file where the test part took place, or
+  // NULL if it's unknown.
+  const char* file_name() const { return file_name_.c_str(); }
+
+  // Gets the line in the source file where the test part took place,
+  // or -1 if it's unknown.
+  int line_number() const { return line_number_; }
+
+  // Gets the message associated with the test part.
+  const char* message() const { return message_.c_str(); }
+
+  // Returns true iff the test part passed.
+  bool passed() const { return type_ == TPRT_SUCCESS; }
+
+  // Returns true iff the test part failed.
+  bool failed() const { return type_ != TPRT_SUCCESS; }
+
+  // Returns true iff the test part non-fatally failed.
+  bool nonfatally_failed() const { return type_ == TPRT_NONFATAL_FAILURE; }
+
+  // Returns true iff the test part fatally failed.
+  bool fatally_failed() const { return type_ == TPRT_FATAL_FAILURE; }
+ private:
+  TestPartResultType type_;
+
+  // The name of the source file where the test part took place, or
+  // NULL if the source file is unknown.
+  internal::String file_name_;
+  // The line in the source file where the test part took place, or -1
+  // if the line number is unknown.
+  int line_number_;
+  internal::String message_;  // The test failure message.
+};
+
+// Prints a TestPartResult object.
+std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
+
+// An array of TestPartResult objects.
+//
+// We define this class as we cannot use STL containers when compiling
+// Google Test with MSVC 7.1 and exceptions disabled.
+//
+// Don't inherit from TestPartResultArray as its destructor is not
+// virtual.
+class TestPartResultArray {
+ public:
+  TestPartResultArray();
+  ~TestPartResultArray();
+
+  // Appends the given TestPartResult to the array.
+  void Append(const TestPartResult& result);
+
+  // Returns the TestPartResult at the given index (0-based).
+  const TestPartResult& GetTestPartResult(int index) const;
+
+  // Returns the number of TestPartResult objects in the array.
+  int size() const;
+ private:
+  // Internally we use a list to simulate the array.  Yes, this means
+  // that random access is O(N) in time, but it's OK for its purpose.
+  internal::List<TestPartResult>* const list_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(TestPartResultArray);
+};
+
+// This interface knows how to report a test part result.
+class TestPartResultReporterInterface {
+ public:
+  virtual ~TestPartResultReporterInterface() {}
+
+  virtual void ReportTestPartResult(const TestPartResult& result) = 0;
+};
+
+// This helper class can be used to mock out Google Test failure reporting
+// so that we can test Google Test or code that builds on Google Test.
+//
+// An object of this class appends a TestPartResult object to the
+// TestPartResultArray object given in the constructor whenever a
+// Google Test failure is reported.
+class ScopedFakeTestPartResultReporter
+    : public TestPartResultReporterInterface {
+ public:
+  // The c'tor sets this object as the test part result reporter used
+  // by Google Test.  The 'result' parameter specifies where to report the
+  // results.
+  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
+
+  // The d'tor restores the previous test part result reporter.
+  virtual ~ScopedFakeTestPartResultReporter();
+
+  // Appends the TestPartResult object to the TestPartResultArray
+  // received in the constructor.
+  //
+  // This method is from the TestPartResultReporterInterface
+  // interface.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+ private:
+  TestPartResultReporterInterface* const old_reporter_;
+  TestPartResultArray* const result_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(ScopedFakeTestPartResultReporter);
+};
+
+namespace internal {
+
+// A helper class for implementing EXPECT_FATAL_FAILURE() and
+// EXPECT_NONFATAL_FAILURE().  Its destructor verifies that the given
+// TestPartResultArray contains exactly one failure that has the given
+// type and contains the given substring.  If that's not the case, a
+// non-fatal failure will be generated.
+class SingleFailureChecker {
+ public:
+  // The constructor remembers the arguments.
+  SingleFailureChecker(const TestPartResultArray* results,
+                       TestPartResultType type,
+                       const char* substr);
+  ~SingleFailureChecker();
+ private:
+  const TestPartResultArray* const results_;
+  const TestPartResultType type_;
+  const String substr_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(SingleFailureChecker);
+};
+
+}  // namespace internal
+
+}  // namespace testing
+
+// A macro for testing Google Test assertions or code that's expected to
+// generate Google Test fatal failures.  It verifies that the given
+// statement will cause exactly one fatal Google Test failure with 'substr'
+// being part of the failure message.
+//
+// Implementation note: The verification is done in the destructor of
+// SingleFailureChecker, to make sure that it's done even when
+// 'statement' throws an exception.
+//
+// Known restrictions:
+//   - 'statement' cannot reference local non-static variables or
+//     non-static members of the current object.
+//   - 'statement' cannot return a value.
+//   - You cannot stream a failure message to this macro.
+#define EXPECT_FATAL_FAILURE(statement, substr) do {\
+    class GTestExpectFatalFailureHelper {\
+     public:\
+      static void Execute() { statement; }\
+    };\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TPRT_FATAL_FAILURE, (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          &gtest_failures);\
+      GTestExpectFatalFailureHelper::Execute();\
+    }\
+  } while (false)
+
+// A macro for testing Google Test assertions or code that's expected to
+// generate Google Test non-fatal failures.  It asserts that the given
+// statement will cause exactly one non-fatal Google Test failure with
+// 'substr' being part of the failure message.
+//
+// 'statement' is allowed to reference local variables and members of
+// the current object.
+//
+// Implementation note: The verification is done in the destructor of
+// SingleFailureChecker, to make sure that it's done even when
+// 'statement' throws an exception or aborts the function.
+//
+// Known restrictions:
+//   - You cannot stream a failure message to this macro.
+#define EXPECT_NONFATAL_FAILURE(statement, substr) do {\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          &gtest_failures);\
+      statement;\
+    }\
+  } while (false)
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
diff --git a/src/gtest/gtest.cc b/src/gtest/gtest.cc
new file mode 100644
index 0000000..1eee392
--- /dev/null
+++ b/src/gtest/gtest.cc
@@ -0,0 +1,3546 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
+#include <ctype.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef GTEST_OS_LINUX
+
+// TODO(kenton):  Use autoconf to detect availability of gettimeofday().
+#define HAS_GETTIMEOFDAY
+
+#include <fcntl.h>
+#include <limits.h>
+#include <sched.h>
+// Declares vsnprintf().  This header is not available on Windows.
+#include <strings.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <string>
+#include <vector>
+
+#elif defined(_WIN32_WCE)  // We are on Windows CE.
+
+#include <windows.h>  // NOLINT
+
+#elif defined(_WIN32)  // We are on Windows proper.
+
+#include <io.h>  // NOLINT
+#include <sys/timeb.h>  // NOLINT
+#include <sys/types.h>  // NOLINT
+#include <sys/stat.h>  // NOLINT
+
+#if defined(__MINGW__) || defined(__MINGW32__)
+// MinGW has gettimeofday() but not _ftime64()
+// TODO(kenton):  Use autoconf to detect availability of gettimeofday().
+// TODO(kenton):  There are other ways to get the time on Windows, like
+//   GetTickCount() or GetSystemTimeAsFileTime().  MinGW supports these.
+//   consider using them instead.
+#define HAS_GETTIMEOFDAY
+#include <sys/time.h>  // NOLINT
+#endif
+
+// cpplint thinks that the header is already included, so we want to
+// silence it.
+#include <windows.h>  // NOLINT
+
+#else
+
+// Assume other platforms have gettimeofday().
+// TODO(kenton):  Use autoconf to detect availability of gettimeofday().
+#define HAS_GETTIMEOFDAY
+
+// cpplint thinks that the header is already included, so we want to
+// silence it.
+#include <sys/time.h>  // NOLINT
+#include <unistd.h>  // NOLINT
+
+#endif
+
+// Indicates that this translation unit is part of Google Test's
+// implementation.  It must come before gtest-internal-inl.h is
+// included, or there will be a compiler error.  This trick is to
+// prevent a user from accidentally including gtest-internal-inl.h in
+// his code.
+#define GTEST_IMPLEMENTATION
+#include <gtest/gtest-internal-inl.h>
+#undef GTEST_IMPLEMENTATION
+
+#ifdef GTEST_OS_WINDOWS
+#define fileno _fileno
+#define isatty _isatty
+#define vsnprintf _vsnprintf
+#endif  // GTEST_OS_WINDOWS
+
+namespace testing {
+
+// Constants.
+
+// A test that matches this pattern is disabled and not run.
+static const char kDisableTestPattern[] = "DISABLED_*";
+
+// A test filter that matches everything.
+static const char kUniversalFilter[] = "*";
+
+// The default output file for XML output.
+static const char kDefaultOutputFile[] = "test_detail.xml";
+
+GTEST_DEFINE_bool(
+    break_on_failure,
+    internal::BoolFromGTestEnv("break_on_failure", false),
+    "True iff a failed assertion should be a debugger break-point.");
+
+GTEST_DEFINE_bool(
+    catch_exceptions,
+    internal::BoolFromGTestEnv("catch_exceptions", false),
+    "True iff " GTEST_NAME
+    " should catch exceptions and treat them as test failures.");
+
+GTEST_DEFINE_string(
+    color,
+    internal::StringFromGTestEnv("color", "auto"),
+    "Whether to use colors in the output.  Valid values: yes, no, "
+    "and auto.  'auto' means to use colors if the output is "
+    "being sent to a terminal and the TERM environment variable "
+    "is set to xterm or xterm-color.");
+
+GTEST_DEFINE_string(
+    filter,
+    internal::StringFromGTestEnv("filter", kUniversalFilter),
+    "A colon-separated list of glob (not regex) patterns "
+    "for filtering the tests to run, optionally followed by a "
+    "'-' and a : separated list of negative patterns (tests to "
+    "exclude).  A test is run if it matches one of the positive "
+    "patterns and does not match any of the negative patterns.");
+
+GTEST_DEFINE_bool(list_tests, false,
+                  "List all tests without running them.");
+
+GTEST_DEFINE_string(
+    output,
+    internal::StringFromGTestEnv("output", ""),
+    "A format (currently must be \"xml\"), optionally followed "
+    "by a colon and an output file name or directory. A directory "
+    "is indicated by a trailing pathname separator. "
+    "Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
+    "If a directory is specified, output files will be created "
+    "within that directory, with file-names based on the test "
+    "executable's name and, if necessary, made unique by adding "
+    "digits.");
+
+GTEST_DEFINE_int32(
+    repeat,
+    internal::Int32FromGTestEnv("repeat", 1),
+    "How many times to repeat each test.  Specify a negative number "
+    "for repeating forever.  Useful for shaking out flaky tests.");
+
+GTEST_DEFINE_int32(
+    stack_trace_depth,
+        internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth),
+    "The maximum number of stack frames to print when an "
+    "assertion fails.  The valid range is 0 through 100, inclusive.");
+
+GTEST_DEFINE_bool(
+    show_internal_stack_frames, false,
+    "True iff " GTEST_NAME " should include internal stack frames when "
+    "printing test failure stack traces.");
+
+namespace internal {
+
+// GTestIsInitialized() returns true iff the user has initialized
+// Google Test.  Useful for catching the user mistake of not initializing
+// Google Test before calling RUN_ALL_TESTS().
+
+// A user must call testing::ParseGTestFlags() to initialize Google
+// Test.  g_parse_gtest_flags_called is set to true iff
+// ParseGTestFlags() has been called.  We don't protect this variable
+// under a mutex as it is only accessed in the main thread.
+static bool g_parse_gtest_flags_called = false;
+static bool GTestIsInitialized() { return g_parse_gtest_flags_called; }
+
+// Iterates over a list of TestCases, keeping a running sum of the
+// results of calling a given int-returning method on each.
+// Returns the sum.
+static int SumOverTestCaseList(const internal::List<TestCase*>& case_list,
+                               int (TestCase::*method)() const) {
+  int sum = 0;
+  for (const internal::ListNode<TestCase*>* node = case_list.Head();
+       node != NULL;
+       node = node->next()) {
+    sum += (node->element()->*method)();
+  }
+  return sum;
+}
+
+// Returns true iff the test case passed.
+static bool TestCasePassed(const TestCase* test_case) {
+  return test_case->should_run() && test_case->Passed();
+}
+
+// Returns true iff the test case failed.
+static bool TestCaseFailed(const TestCase* test_case) {
+  return test_case->should_run() && test_case->Failed();
+}
+
+// Returns true iff test_case contains at least one test that should
+// run.
+static bool ShouldRunTestCase(const TestCase* test_case) {
+  return test_case->should_run();
+}
+
+#ifdef _WIN32_WCE
+// Windows CE has no C library. The abort() function is used in
+// several places in Google Test. This implementation provides a reasonable
+// imitation of standard behaviour.
+static void abort() {
+  DebugBreak();
+  TerminateProcess(GetCurrentProcess(), 1);
+}
+#endif  // _WIN32_WCE
+
+// AssertHelper constructor.
+AssertHelper::AssertHelper(TestPartResultType type, const char* file,
+                           int line, const char* message)
+    : type_(type), file_(file), line_(line), message_(message) {
+}
+
+// Message assignment, for assertion streaming support.
+void AssertHelper::operator=(const Message& message) const {
+  UnitTest::GetInstance()->
+    AddTestPartResult(type_, file_, line_,
+                      AppendUserMessage(message_, message),
+                      UnitTest::GetInstance()->impl()
+                      ->CurrentOsStackTraceExceptTop(1)
+                      // Skips the stack frame for this function itself.
+                      );  // NOLINT
+}
+
+// Application pathname gotten in ParseGTestFlags.
+String g_executable_path;
+
+// Returns the current application's name, removing directory path if that
+// is present.
+FilePath GetCurrentExecutableName() {
+  FilePath result;
+
+#if defined(_WIN32_WCE) || defined(_WIN32)
+  result.Set(FilePath(g_executable_path).RemoveExtension("exe"));
+#else
+  result.Set(FilePath(g_executable_path));
+#endif  // _WIN32_WCE || _WIN32
+
+  return result.RemoveDirectoryName();
+}
+
+// Functions for processing the gtest_output flag.
+
+// Returns the output format, or "" for normal printed output.
+String UnitTestOptions::GetOutputFormat() {
+  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
+  if (gtest_output_flag == NULL) return String("");
+
+  const char* const colon = strchr(gtest_output_flag, ':');
+  return (colon == NULL) ?
+      String(gtest_output_flag) :
+      String(gtest_output_flag, colon - gtest_output_flag);
+}
+
+// Returns the name of the requested output file, or the default if none
+// was explicitly specified.
+String UnitTestOptions::GetOutputFile() {
+  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
+  if (gtest_output_flag == NULL)
+    return String("");
+
+  const char* const colon = strchr(gtest_output_flag, ':');
+  if (colon == NULL)
+    return String(kDefaultOutputFile);
+
+  internal::FilePath output_name(colon + 1);
+  if (!output_name.IsDirectory())
+    return output_name.ToString();
+
+  internal::FilePath result(internal::FilePath::GenerateUniqueFileName(
+      output_name, internal::GetCurrentExecutableName(),
+      GetOutputFormat().c_str()));
+  return result.ToString();
+}
+
+// Returns true iff the wildcard pattern matches the string.  The
+// first ':' or '\0' character in pattern marks the end of it.
+//
+// This recursive algorithm isn't very efficient, but is clear and
+// works well enough for matching test names, which are short.
+bool UnitTestOptions::PatternMatchesString(const char *pattern,
+                                           const char *str) {
+  switch (*pattern) {
+    case '\0':
+    case ':':  // Either ':' or '\0' marks the end of the pattern.
+      return *str == '\0';
+    case '?':  // Matches any single character.
+      return *str != '\0' && PatternMatchesString(pattern + 1, str + 1);
+    case '*':  // Matches any string (possibly empty) of characters.
+      return (*str != '\0' && PatternMatchesString(pattern, str + 1)) ||
+          PatternMatchesString(pattern + 1, str);
+    default:  // Non-special character.  Matches itself.
+      return *pattern == *str &&
+          PatternMatchesString(pattern + 1, str + 1);
+  }
+}
+
+bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) {
+  const char *cur_pattern = filter;
+  while (true) {
+    if (PatternMatchesString(cur_pattern, name.c_str())) {
+      return true;
+    }
+
+    // Finds the next pattern in the filter.
+    cur_pattern = strchr(cur_pattern, ':');
+
+    // Returns if no more pattern can be found.
+    if (cur_pattern == NULL) {
+      return false;
+    }
+
+    // Skips the pattern separater (the ':' character).
+    cur_pattern++;
+  }
+}
+
+// TODO(keithray): move String function implementations to gtest-string.cc.
+
+// Returns true iff the user-specified filter matches the test case
+// name and the test name.
+bool UnitTestOptions::FilterMatchesTest(const String &test_case_name,
+                                        const String &test_name) {
+  const String& full_name = String::Format("%s.%s",
+                                           test_case_name.c_str(),
+                                           test_name.c_str());
+
+  // Split --gtest_filter at '-', if there is one, to separate into
+  // positive filter and negative filter portions
+  const char* const p = GTEST_FLAG(filter).c_str();
+  const char* const dash = strchr(p, '-');
+  String positive;
+  String negative;
+  if (dash == NULL) {
+    positive = GTEST_FLAG(filter).c_str();  // Whole string is a positive filter
+    negative = String("");
+  } else {
+    positive.Set(p, dash - p);       // Everything up to the dash
+    negative = String(dash+1);       // Everything after the dash
+    if (positive.empty()) {
+      // Treat '-test1' as the same as '*-test1'
+      positive = kUniversalFilter;
+    }
+  }
+
+  // A filter is a colon-separated list of patterns.  It matches a
+  // test if any pattern in it matches the test.
+  return (MatchesFilter(full_name, positive.c_str()) &&
+          !MatchesFilter(full_name, negative.c_str()));
+}
+
+#ifdef GTEST_OS_WINDOWS
+// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
+// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
+// This function is useful as an __except condition.
+int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
+  // Google Test should handle an exception if:
+  //   1. the user wants it to, AND
+  //   2. this is not a breakpoint exception.
+  return (GTEST_FLAG(catch_exceptions) &&
+          exception_code != EXCEPTION_BREAKPOINT) ?
+      EXCEPTION_EXECUTE_HANDLER :
+      EXCEPTION_CONTINUE_SEARCH;
+}
+#endif  // GTEST_OS_WINDOWS
+
+}  // namespace internal
+
+// The interface for printing the result of a UnitTest
+class UnitTestEventListenerInterface {
+ public:
+  // The d'tor is pure virtual as this is an abstract class.
+  virtual ~UnitTestEventListenerInterface() = 0;
+
+  // Called before the unit test starts.
+  virtual void OnUnitTestStart(const UnitTest*) {}
+
+  // Called after the unit test ends.
+  virtual void OnUnitTestEnd(const UnitTest*) {}
+
+  // Called before the test case starts.
+  virtual void OnTestCaseStart(const TestCase*) {}
+
+  // Called after the test case ends.
+  virtual void OnTestCaseEnd(const TestCase*) {}
+
+  // Called before the global set-up starts.
+  virtual void OnGlobalSetUpStart(const UnitTest*) {}
+
+  // Called after the global set-up ends.
+  virtual void OnGlobalSetUpEnd(const UnitTest*) {}
+
+  // Called before the global tear-down starts.
+  virtual void OnGlobalTearDownStart(const UnitTest*) {}
+
+  // Called after the global tear-down ends.
+  virtual void OnGlobalTearDownEnd(const UnitTest*) {}
+
+  // Called before the test starts.
+  virtual void OnTestStart(const TestInfo*) {}
+
+  // Called after the test ends.
+  virtual void OnTestEnd(const TestInfo*) {}
+
+  // Called after an assertion.
+  virtual void OnNewTestPartResult(const TestPartResult*) {}
+};
+
+// Constructs an empty TestPartResultArray.
+TestPartResultArray::TestPartResultArray()
+    : list_(new internal::List<TestPartResult>) {
+}
+
+// Destructs a TestPartResultArray.
+TestPartResultArray::~TestPartResultArray() {
+  delete list_;
+}
+
+// Appends a TestPartResult to the array.
+void TestPartResultArray::Append(const TestPartResult& result) {
+  list_->PushBack(result);
+}
+
+// Returns the TestPartResult at the given index (0-based).
+const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {
+  if (index < 0 || index >= size()) {
+    printf("\nInvalid index (%d) into TestPartResultArray.\n", index);
+    abort();
+  }
+
+  const internal::ListNode<TestPartResult>* p = list_->Head();
+  for (int i = 0; i < index; i++) {
+    p = p->next();
+  }
+
+  return p->element();
+}
+
+// Returns the number of TestPartResult objects in the array.
+int TestPartResultArray::size() const {
+  return list_->size();
+}
+
+// The c'tor sets this object as the test part result reporter used by
+// Google Test.  The 'result' parameter specifies where to report the
+// results.
+ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
+    TestPartResultArray* result)
+    : old_reporter_(UnitTest::GetInstance()->impl()->
+                    test_part_result_reporter()),
+      result_(result) {
+  internal::UnitTestImpl* const impl = UnitTest::GetInstance()->impl();
+  impl->set_test_part_result_reporter(this);
+}
+
+// The d'tor restores the test part result reporter used by Google Test
+// before.
+ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {
+  UnitTest::GetInstance()->impl()->
+      set_test_part_result_reporter(old_reporter_);
+}
+
+// Increments the test part result count and remembers the result.
+// This method is from the TestPartResultReporterInterface interface.
+void ScopedFakeTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  result_->Append(result);
+}
+
+namespace internal {
+
+// This predicate-formatter checks that 'results' contains a test part
+// failure of the given type and that the failure message contains the
+// given substring.
+AssertionResult HasOneFailure(const char* /* results_expr */,
+                              const char* /* type_expr */,
+                              const char* /* substr_expr */,
+                              const TestPartResultArray& results,
+                              TestPartResultType type,
+                              const char* substr) {
+  const String expected(
+      type == TPRT_FATAL_FAILURE ? "1 fatal failure" :
+      "1 non-fatal failure");
+  Message msg;
+  if (results.size() != 1) {
+    msg << "Expected: " << expected << "\n"
+        << "  Actual: " << results.size() << " failures";
+    for (int i = 0; i < results.size(); i++) {
+      msg << "\n" << results.GetTestPartResult(i);
+    }
+    return AssertionFailure(msg);
+  }
+
+  const TestPartResult& r = results.GetTestPartResult(0);
+  if (r.type() != type) {
+    msg << "Expected: " << expected << "\n"
+        << "  Actual:\n"
+        << r;
+    return AssertionFailure(msg);
+  }
+
+  if (strstr(r.message(), substr) == NULL) {
+    msg << "Expected: " << expected << " containing \""
+        << substr << "\"\n"
+        << "  Actual:\n"
+        << r;
+    return AssertionFailure(msg);
+  }
+
+  return AssertionSuccess();
+}
+
+// The constructor of SingleFailureChecker remembers where to look up
+// test part results, what type of failure we expect, and what
+// substring the failure message should contain.
+SingleFailureChecker:: SingleFailureChecker(
+    const TestPartResultArray* results,
+    TestPartResultType type,
+    const char* substr)
+    : results_(results),
+      type_(type),
+      substr_(substr) {}
+
+// The destructor of SingleFailureChecker verifies that the given
+// TestPartResultArray contains exactly one failure that has the given
+// type and contains the given substring.  If that's not the case, a
+// non-fatal failure will be generated.
+SingleFailureChecker::~SingleFailureChecker() {
+  EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_.c_str());
+}
+
+// Reports a test part result.
+void UnitTestImpl::ReportTestPartResult(const TestPartResult& result) {
+  current_test_result()->AddTestPartResult(result);
+  result_printer()->OnNewTestPartResult(&result);
+}
+
+// Returns the current test part result reporter.
+TestPartResultReporterInterface* UnitTestImpl::test_part_result_reporter() {
+  return test_part_result_reporter_;
+}
+
+// Sets the current test part result reporter.
+void UnitTestImpl::set_test_part_result_reporter(
+    TestPartResultReporterInterface* reporter) {
+  test_part_result_reporter_ = reporter;
+}
+
+// Gets the number of successful test cases.
+int UnitTestImpl::successful_test_case_count() const {
+  return test_cases_.CountIf(TestCasePassed);
+}
+
+// Gets the number of failed test cases.
+int UnitTestImpl::failed_test_case_count() const {
+  return test_cases_.CountIf(TestCaseFailed);
+}
+
+// Gets the number of all test cases.
+int UnitTestImpl::total_test_case_count() const {
+  return test_cases_.size();
+}
+
+// Gets the number of all test cases that contain at least one test
+// that should run.
+int UnitTestImpl::test_case_to_run_count() const {
+  return test_cases_.CountIf(ShouldRunTestCase);
+}
+
+// Gets the number of successful tests.
+int UnitTestImpl::successful_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count);
+}
+
+// Gets the number of failed tests.
+int UnitTestImpl::failed_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count);
+}
+
+// Gets the number of disabled tests.
+int UnitTestImpl::disabled_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count);
+}
+
+// Gets the number of all tests.
+int UnitTestImpl::total_test_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::total_test_count);
+}
+
+// Gets the number of tests that should run.
+int UnitTestImpl::test_to_run_count() const {
+  return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count);
+}
+
+// Returns the current OS stack trace as a String.
+//
+// The maximum number of stack frames to be included is specified by
+// the gtest_stack_trace_depth flag.  The skip_count parameter
+// specifies the number of top frames to be skipped, which doesn't
+// count against the number of frames to be included.
+//
+// For example, if Foo() calls Bar(), which in turn calls
+// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
+// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
+String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {
+  (void)skip_count;
+  return String("");
+}
+
+static TimeInMillis GetTimeInMillis() {
+#ifdef _WIN32_WCE  // We are on Windows CE
+  // Difference between 1970-01-01 and 1601-01-01 in miliseconds.
+  // http://analogous.blogspot.com/2005/04/epoch.html
+  const TimeInMillis kJavaEpochToWinFileTimeDelta = 11644473600000UL;
+  const DWORD kTenthMicrosInMilliSecond = 10000;
+
+  SYSTEMTIME now_systime;
+  FILETIME now_filetime;
+  ULARGE_INTEGER now_int64;
+  // TODO(kenton):  Shouldn't this just use GetSystemTimeAsFileTime()?
+  GetSystemTime(&now_systime);
+  if (SystemTimeToFileTime(&now_systime, &now_filetime)) {
+    now_int64.LowPart = now_filetime.dwLowDateTime;
+    now_int64.HighPart = now_filetime.dwHighDateTime;
+    now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) -
+      kJavaEpochToWinFileTimeDelta;
+    return now_int64.QuadPart;
+  }
+  return 0;
+#elif defined(_WIN32) && !defined(HAS_GETTIMEOFDAY)
+  __timeb64 now;
+#ifdef _MSC_VER
+  // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
+  // (deprecated function) there.
+  // TODO(kenton):  Use GetTickCount()?  Or use SystemTimeToFileTime()
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4996)  // Temporarily disables warning 4996.
+  _ftime64(&now);
+#pragma warning(pop)           // Restores the warning state.
+#else
+  _ftime64(&now);
+#endif  // _MSC_VER
+  return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;
+#elif defined(HAS_GETTIMEOFDAY)
+  struct timeval now;
+  gettimeofday(&now, NULL);
+  return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000;
+#else
+#error "Don't know how to get the current time on your system."
+  return 0;
+#endif
+}
+
+// Utilities
+
+// class String
+
+// Returns the input enclosed in double quotes if it's not NULL;
+// otherwise returns "(null)".  For example, "\"Hello\"" is returned
+// for input "Hello".
+//
+// This is useful for printing a C string in the syntax of a literal.
+//
+// Known issue: escape sequences are not handled yet.
+String String::ShowCStringQuoted(const char* c_str) {
+  return c_str ? String::Format("\"%s\"", c_str) : String("(null)");
+}
+
+// Copies at most length characters from str into a newly-allocated
+// piece of memory of size length+1.  The memory is allocated with new[].
+// A terminating null byte is written to the memory, and a pointer to it
+// is returned.  If str is NULL, NULL is returned.
+static char* CloneString(const char* str, size_t length) {
+  if (str == NULL) {
+    return NULL;
+  } else {
+    char* const clone = new char[length + 1];
+    // MSVC 8 deprecates strncpy(), so we want to suppress warning
+    // 4996 (deprecated function) there.
+#ifdef GTEST_OS_WINDOWS  // We are on Windows.
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4996)  // Temporarily disables warning 4996.
+    strncpy(clone, str, length);
+#pragma warning(pop)           // Restores the warning state.
+#else  // We are on Linux or Mac OS.
+    strncpy(clone, str, length);
+#endif  // GTEST_OS_WINDOWS
+    clone[length] = '\0';
+    return clone;
+  }
+}
+
+// Clones a 0-terminated C string, allocating memory using new.  The
+// caller is responsible for deleting[] the return value.  Returns the
+// cloned string, or NULL if the input is NULL.
+const char * String::CloneCString(const char* c_str) {
+  return (c_str == NULL) ?
+                    NULL : CloneString(c_str, strlen(c_str));
+}
+
+// Compares two C strings.  Returns true iff they have the same content.
+//
+// Unlike strcmp(), this function can handle NULL argument(s).  A NULL
+// C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::CStringEquals(const char * lhs, const char * rhs) {
+  if ( lhs == NULL ) return rhs == NULL;
+
+  if ( rhs == NULL ) return false;
+
+  return strcmp(lhs, rhs) == 0;
+}
+
+#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
+
+// Converts an array of wide chars to a narrow string using the UTF-8
+// encoding, and streams the result to the given Message object.
+static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len,
+                                     Message* msg) {
+  for (size_t i = 0; i != len; i++) {
+    // TODO(wan): consider allowing a testing::String object to
+    // contain '\0'.  This will make it behave more like std::string,
+    // and will allow ToUtf8String() to return the correct encoding
+    // for '\0' s.t. we can get rid of the conditional here (and in
+    // several other places).
+    if (wstr[i]) {
+      *msg << internal::ToUtf8String(wstr[i]);
+    } else {
+      *msg << '\0';
+    }
+  }
+}
+
+#endif  // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
+
+}  // namespace internal
+
+#if GTEST_HAS_STD_WSTRING
+// Converts the given wide string to a narrow string using the UTF-8
+// encoding, and streams the result to this Message object.
+Message& Message::operator <<(const ::std::wstring& wstr) {
+  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
+  return *this;
+}
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+// Converts the given wide string to a narrow string using the UTF-8
+// encoding, and streams the result to this Message object.
+Message& Message::operator <<(const ::wstring& wstr) {
+  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
+  return *this;
+}
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+namespace internal {
+
+// Formats a value to be used in a failure message.
+
+// For a char value, we print it as a C++ char literal and as an
+// unsigned integer (both in decimal and in hexadecimal).
+String FormatForFailureMessage(char ch) {
+  const unsigned int ch_as_uint = ch;
+  // A String object cannot contain '\0', so we print "\\0" when ch is
+  // '\0'.
+  return String::Format("'%s' (%u, 0x%X)",
+                        ch ? String::Format("%c", ch).c_str() : "\\0",
+                        ch_as_uint, ch_as_uint);
+}
+
+// For a wchar_t value, we print it as a C++ wchar_t literal and as an
+// unsigned integer (both in decimal and in hexidecimal).
+String FormatForFailureMessage(wchar_t wchar) {
+  // The C++ standard doesn't specify the exact size of the wchar_t
+  // type.  It just says that it shall have the same size as another
+  // integral type, called its underlying type.
+  //
+  // Therefore, in order to print a wchar_t value in the numeric form,
+  // we first convert it to the largest integral type (UInt64) and
+  // then print the converted value.
+  //
+  // We use streaming to print the value as "%llu" doesn't work
+  // correctly with MSVC 7.1.
+  const UInt64 wchar_as_uint64 = wchar;
+  Message msg;
+  // A String object cannot contain '\0', so we print "\\0" when wchar is
+  // L'\0'.
+  msg << "L'" << (wchar ? ToUtf8String(wchar).c_str() : "\\0") << "' ("
+      << wchar_as_uint64 << ", 0x" << ::std::setbase(16)
+      << wchar_as_uint64 << ")";
+  return msg.GetString();
+}
+
+}  // namespace internal
+
+// AssertionResult constructor.
+AssertionResult::AssertionResult(const internal::String& failure_message)
+    : failure_message_(failure_message) {
+}
+
+
+// Makes a successful assertion result.
+AssertionResult AssertionSuccess() {
+  return AssertionResult();
+}
+
+
+// Makes a failed assertion result with the given failure message.
+AssertionResult AssertionFailure(const Message& message) {
+  return AssertionResult(message.GetString());
+}
+
+namespace internal {
+
+// Constructs and returns the message for an equality assertion
+// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
+//
+// The first four parameters are the expressions used in the assertion
+// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)
+// where foo is 5 and bar is 6, we have:
+//
+//   expected_expression: "foo"
+//   actual_expression:   "bar"
+//   expected_value:      "5"
+//   actual_value:        "6"
+//
+// The ignoring_case parameter is true iff the assertion is a
+// *_STRCASEEQ*.  When it's true, the string " (ignoring case)" will
+// be inserted into the message.
+AssertionResult EqFailure(const char* expected_expression,
+                          const char* actual_expression,
+                          const String& expected_value,
+                          const String& actual_value,
+                          bool ignoring_case) {
+  Message msg;
+  msg << "Value of: " << actual_expression;
+  if (actual_value != actual_expression) {
+    msg << "\n  Actual: " << actual_value;
+  }
+
+  msg << "\nExpected: " << expected_expression;
+  if (ignoring_case) {
+    msg << " (ignoring case)";
+  }
+  if (expected_value != expected_expression) {
+    msg << "\nWhich is: " << expected_value;
+  }
+
+  return AssertionFailure(msg);
+}
+
+
+// Helper function for implementing ASSERT_NEAR.
+AssertionResult DoubleNearPredFormat(const char* expr1,
+                                     const char* expr2,
+                                     const char* abs_error_expr,
+                                     double val1,
+                                     double val2,
+                                     double abs_error) {
+  const double diff = fabs(val1 - val2);
+  if (diff <= abs_error) return AssertionSuccess();
+
+  // TODO(wan): do not print the value of an expression if it's
+  // already a literal.
+  Message msg;
+  msg << "The difference between " << expr1 << " and " << expr2
+      << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n"
+      << expr1 << " evaluates to " << val1 << ",\n"
+      << expr2 << " evaluates to " << val2 << ", and\n"
+      << abs_error_expr << " evaluates to " << abs_error << ".";
+  return AssertionFailure(msg);
+}
+
+
+// Helper template for implementing FloatLE() and DoubleLE().
+template <typename RawType>
+AssertionResult FloatingPointLE(const char* expr1,
+                                const char* expr2,
+                                RawType val1,
+                                RawType val2) {
+  // Returns success if val1 is less than val2,
+  if (val1 < val2) {
+    return AssertionSuccess();
+  }
+
+  // or if val1 is almost equal to val2.
+  const FloatingPoint<RawType> lhs(val1), rhs(val2);
+  if (lhs.AlmostEquals(rhs)) {
+    return AssertionSuccess();
+  }
+
+  // Note that the above two checks will both fail if either val1 or
+  // val2 is NaN, as the IEEE floating-point standard requires that
+  // any predicate involving a NaN must return false.
+
+  StrStream val1_ss;
+  val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+          << val1;
+
+  StrStream val2_ss;
+  val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+          << val2;
+
+  Message msg;
+  msg << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n"
+      << "  Actual: " << StrStreamToString(&val1_ss) << " vs "
+      << StrStreamToString(&val2_ss);
+
+  return AssertionFailure(msg);
+}
+
+}  // namespace internal
+
+// Asserts that val1 is less than, or almost equal to, val2.  Fails
+// otherwise.  In particular, it fails if either val1 or val2 is NaN.
+AssertionResult FloatLE(const char* expr1, const char* expr2,
+                        float val1, float val2) {
+  return internal::FloatingPointLE<float>(expr1, expr2, val1, val2);
+}
+
+// Asserts that val1 is less than, or almost equal to, val2.  Fails
+// otherwise.  In particular, it fails if either val1 or val2 is NaN.
+AssertionResult DoubleLE(const char* expr1, const char* expr2,
+                         double val1, double val2) {
+  return internal::FloatingPointLE<double>(expr1, expr2, val1, val2);
+}
+
+namespace internal {
+
+// The helper function for {ASSERT|EXPECT}_EQ with int or enum
+// arguments.
+AssertionResult CmpHelperEQ(const char* expected_expression,
+                            const char* actual_expression,
+                            BiggestInt expected,
+                            BiggestInt actual) {
+  if (expected == actual) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   FormatForComparisonFailureMessage(expected, actual),
+                   FormatForComparisonFailureMessage(actual, expected),
+                   false);
+}
+
+// A macro for implementing the helper functions needed to implement
+// ASSERT_?? and EXPECT_?? with integer or enum arguments.  It is here
+// just to avoid copy-and-paste of similar code.
+#define GTEST_IMPL_CMP_HELPER(op_name, op)\
+AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
+                                   BiggestInt val1, BiggestInt val2) {\
+  if (val1 op val2) {\
+    return AssertionSuccess();\
+  } else {\
+    Message msg;\
+    msg << "Expected: (" << expr1 << ") " #op " (" << expr2\
+        << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\
+        << " vs " << FormatForComparisonFailureMessage(val2, val1);\
+    return AssertionFailure(msg);\
+  }\
+}
+
+// Implements the helper function for {ASSERT|EXPECT}_NE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER(NE, !=)
+// Implements the helper function for {ASSERT|EXPECT}_LE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER(LE, <=)
+// Implements the helper function for {ASSERT|EXPECT}_LT with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER(LT, < )
+// Implements the helper function for {ASSERT|EXPECT}_GE with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER(GE, >=)
+// Implements the helper function for {ASSERT|EXPECT}_GT with int or
+// enum arguments.
+GTEST_IMPL_CMP_HELPER(GT, > )
+
+#undef GTEST_IMPL_CMP_HELPER
+
+// The helper function for {ASSERT|EXPECT}_STREQ.
+AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                               const char* actual_expression,
+                               const char* expected,
+                               const char* actual) {
+  if (String::CStringEquals(expected, actual)) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   String::ShowCStringQuoted(expected),
+                   String::ShowCStringQuoted(actual),
+                   false);
+}
+
+// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
+AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
+                                   const char* actual_expression,
+                                   const char* expected,
+                                   const char* actual) {
+  if (String::CaseInsensitiveCStringEquals(expected, actual)) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   String::ShowCStringQuoted(expected),
+                   String::ShowCStringQuoted(actual),
+                   true);
+}
+
+// The helper function for {ASSERT|EXPECT}_STRNE.
+AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                               const char* s2_expression,
+                               const char* s1,
+                               const char* s2) {
+  if (!String::CStringEquals(s1, s2)) {
+    return AssertionSuccess();
+  } else {
+    Message msg;
+    msg << "Expected: (" << s1_expression << ") != ("
+        << s2_expression << "), actual: \""
+        << s1 << "\" vs \"" << s2 << "\"";
+    return AssertionFailure(msg);
+  }
+}
+
+// The helper function for {ASSERT|EXPECT}_STRCASENE.
+AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
+                                   const char* s2_expression,
+                                   const char* s1,
+                                   const char* s2) {
+  if (!String::CaseInsensitiveCStringEquals(s1, s2)) {
+    return AssertionSuccess();
+  } else {
+    Message msg;
+    msg << "Expected: (" << s1_expression << ") != ("
+        << s2_expression << ") (ignoring case), actual: \""
+        << s1 << "\" vs \"" << s2 << "\"";
+    return AssertionFailure(msg);
+  }
+}
+
+}  // namespace internal
+
+namespace {
+
+// Helper functions for implementing IsSubString() and IsNotSubstring().
+
+// This group of overloaded functions return true iff needle is a
+// substring of haystack.  NULL is considered a substring of itself
+// only.
+
+bool IsSubstringPred(const char* needle, const char* haystack) {
+  if (needle == NULL || haystack == NULL)
+    return needle == haystack;
+
+  return strstr(haystack, needle) != NULL;
+}
+
+bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
+  if (needle == NULL || haystack == NULL)
+    return needle == haystack;
+
+  return wcsstr(haystack, needle) != NULL;
+}
+
+// StringType here can be either ::std::string or ::std::wstring.
+template <typename StringType>
+bool IsSubstringPred(const StringType& needle,
+                     const StringType& haystack) {
+  return haystack.find(needle) != StringType::npos;
+}
+
+// This function implements either IsSubstring() or IsNotSubstring(),
+// depending on the value of the expected_to_be_substring parameter.
+// StringType here can be const char*, const wchar_t*, ::std::string,
+// or ::std::wstring.
+template <typename StringType>
+AssertionResult IsSubstringImpl(
+    bool expected_to_be_substring,
+    const char* needle_expr, const char* haystack_expr,
+    const StringType& needle, const StringType& haystack) {
+  if (IsSubstringPred(needle, haystack) == expected_to_be_substring)
+    return AssertionSuccess();
+
+  const bool is_wide_string = sizeof(needle[0]) > 1;
+  const char* const begin_string_quote = is_wide_string ? "L\"" : "\"";
+  return AssertionFailure(
+      Message()
+      << "Value of: " << needle_expr << "\n"
+      << "  Actual: " << begin_string_quote << needle << "\"\n"
+      << "Expected: " << (expected_to_be_substring ? "" : "not ")
+      << "a substring of " << haystack_expr << "\n"
+      << "Which is: " << begin_string_quote << haystack << "\"");
+}
+
+}  // namespace
+
+// IsSubstring() and IsNotSubstring() check whether needle is a
+// substring of haystack (NULL is considered a substring of itself
+// only), and return an appropriate error message when they fail.
+
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+
+#if GTEST_HAS_STD_STRING
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+#endif  // GTEST_HAS_STD_STRING
+
+#if GTEST_HAS_STD_WSTRING
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack) {
+  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
+}
+
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack) {
+  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
+}
+#endif  // GTEST_HAS_STD_WSTRING
+
+namespace internal {
+
+#ifdef GTEST_OS_WINDOWS
+
+namespace {
+
+// Helper function for IsHRESULT{SuccessFailure} predicates
+AssertionResult HRESULTFailureHelper(const char* expr,
+                                     const char* expected,
+                                     long hr) {  // NOLINT
+#ifdef _WIN32_WCE
+  // Windows CE doesn't support FormatMessage.
+  const char error_text[] = "";
+#else
+  // Looks up the human-readable system message for the HRESULT code
+  // and since we're not passing any params to FormatMessage, we don't
+  // want inserts expanded.
+  const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS;
+  const DWORD kBufSize = 4096;  // String::Format can't exceed this length.
+  // Gets the system's human readable message string for this HRESULT.
+  char error_text[kBufSize] = { '\0' };
+  DWORD message_length = ::FormatMessageA(kFlags,
+                                          0,  // no source, we're asking system
+                                          hr,  // the error
+                                          0,  // no line width restrictions
+                                          error_text,  // output buffer
+                                          kBufSize,  // buf size
+                                          NULL);  // no arguments for inserts
+  // Trims tailing white space (FormatMessage leaves a trailing cr-lf)
+  for (; message_length && isspace(error_text[message_length - 1]);
+          --message_length) {
+    error_text[message_length - 1] = '\0';
+  }
+#endif  // _WIN32_WCE
+
+  const String error_hex(String::Format("0x%08X ", hr));
+  Message msg;
+  msg << "Expected: " << expr << " " << expected << ".\n"
+      << "  Actual: " << error_hex << error_text << "\n";
+
+  return ::testing::AssertionFailure(msg);
+}
+
+}  // namespace
+
+AssertionResult IsHRESULTSuccess(const char* expr, long hr) {  // NOLINT
+  if (SUCCEEDED(hr)) {
+    return AssertionSuccess();
+  }
+  return HRESULTFailureHelper(expr, "succeeds", hr);
+}
+
+AssertionResult IsHRESULTFailure(const char* expr, long hr) {  // NOLINT
+  if (FAILED(hr)) {
+    return AssertionSuccess();
+  }
+  return HRESULTFailureHelper(expr, "fails", hr);
+}
+
+#endif  // GTEST_OS_WINDOWS
+
+// Utility functions for encoding Unicode text (wide strings) in
+// UTF-8.
+
+// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8
+// like this:
+//
+// Code-point length   Encoding
+//   0 -  7 bits       0xxxxxxx
+//   8 - 11 bits       110xxxxx 10xxxxxx
+//  12 - 16 bits       1110xxxx 10xxxxxx 10xxxxxx
+//  17 - 21 bits       11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+
+// The maximum code-point a one-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) <<  7) - 1;
+
+// The maximum code-point a two-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1;
+
+// The maximum code-point a three-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1;
+
+// The maximum code-point a four-byte UTF-8 sequence can represent.
+const UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1;
+
+// Chops off the n lowest bits from a bit pattern.  Returns the n
+// lowest bits.  As a side effect, the original bit pattern will be
+// shifted to the right by n bits.
+inline UInt32 ChopLowBits(UInt32* bits, int n) {
+  const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1);
+  *bits >>= n;
+  return low_bits;
+}
+
+// Converts a Unicode code-point to its UTF-8 encoding.
+String ToUtf8String(wchar_t wchar) {
+  char str[5] = {};  // Initializes str to all '\0' characters.
+
+  UInt32 code = static_cast<UInt32>(wchar);
+  if (code <= kMaxCodePoint1) {
+    str[0] = static_cast<char>(code);                          // 0xxxxxxx
+  } else if (code <= kMaxCodePoint2) {
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xC0 | code);                   // 110xxxxx
+  } else if (code <= kMaxCodePoint3) {
+    str[2] = static_cast<char>(0x80 | ChopLowBits(&code, 6));  // 10xxxxxx
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xE0 | code);                   // 1110xxxx
+  } else if (code <= kMaxCodePoint4) {
+    str[3] = static_cast<char>(0x80 | ChopLowBits(&code, 6));  // 10xxxxxx
+    str[2] = static_cast<char>(0x80 | ChopLowBits(&code, 6));  // 10xxxxxx
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xF0 | code);                   // 11110xxx
+  } else {
+    return String::Format("(Invalid Unicode 0x%llX)",
+                          static_cast<UInt64>(wchar));
+  }
+
+  return String(str);
+}
+
+// Converts a wide C string to a String using the UTF-8 encoding.
+// NULL will be converted to "(null)".
+String String::ShowWideCString(const wchar_t * wide_c_str) {
+  if (wide_c_str == NULL) return String("(null)");
+
+  StrStream ss;
+  while (*wide_c_str) {
+    ss << internal::ToUtf8String(*wide_c_str++);
+  }
+
+  return internal::StrStreamToString(&ss);
+}
+
+// Similar to ShowWideCString(), except that this function encloses
+// the converted string in double quotes.
+String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) {
+  if (wide_c_str == NULL) return String("(null)");
+
+  return String::Format("L\"%s\"",
+                        String::ShowWideCString(wide_c_str).c_str());
+}
+
+// Compares two wide C strings.  Returns true iff they have the same
+// content.
+//
+// Unlike wcscmp(), this function can handle NULL argument(s).  A NULL
+// C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) {
+  if (lhs == NULL) return rhs == NULL;
+
+  if (rhs == NULL) return false;
+
+  return wcscmp(lhs, rhs) == 0;
+}
+
+// Helper function for *_STREQ on wide strings.
+AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                               const char* actual_expression,
+                               const wchar_t* expected,
+                               const wchar_t* actual) {
+  if (String::WideCStringEquals(expected, actual)) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   String::ShowWideCStringQuoted(expected),
+                   String::ShowWideCStringQuoted(actual),
+                   false);
+}
+
+// Helper function for *_STRNE on wide strings.
+AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                               const char* s2_expression,
+                               const wchar_t* s1,
+                               const wchar_t* s2) {
+  if (!String::WideCStringEquals(s1, s2)) {
+    return AssertionSuccess();
+  }
+
+  Message msg;
+  msg << "Expected: (" << s1_expression << ") != ("
+      << s2_expression << "), actual: "
+      << String::ShowWideCStringQuoted(s1)
+      << " vs " << String::ShowWideCStringQuoted(s2);
+  return AssertionFailure(msg);
+}
+
+// Compares two C strings, ignoring case.  Returns true iff they have
+// the same content.
+//
+// Unlike strcasecmp(), this function can handle NULL argument(s).  A
+// NULL C string is considered different to any non-NULL C string,
+// including the empty string.
+bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) {
+  if ( lhs == NULL ) return rhs == NULL;
+
+  if ( rhs == NULL ) return false;
+
+#ifdef GTEST_OS_WINDOWS
+  return _stricmp(lhs, rhs) == 0;
+#else  // GTEST_OS_WINDOWS
+  return strcasecmp(lhs, rhs) == 0;
+#endif  // GTEST_OS_WINDOWS
+}
+
+// Constructs a String by copying a given number of chars from a
+// buffer.  E.g. String("hello", 3) will create the string "hel".
+String::String(const char * buffer, size_t len) {
+  char * const temp = new char[ len + 1 ];
+  memcpy(temp, buffer, len);
+  temp[ len ] = '\0';
+  c_str_ = temp;
+}
+
+// Compares this with another String.
+// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0
+// if this is greater than rhs.
+int String::Compare(const String & rhs) const {
+  if ( c_str_ == NULL ) {
+    return rhs.c_str_ == NULL ? 0 : -1;  // NULL < anything except NULL
+  }
+
+  return rhs.c_str_ == NULL ? 1 : strcmp(c_str_, rhs.c_str_);
+}
+
+// Returns true iff this String ends with the given suffix.  *Any*
+// String is considered to end with a NULL or empty suffix.
+bool String::EndsWith(const char* suffix) const {
+  if (suffix == NULL || CStringEquals(suffix, "")) return true;
+
+  if (c_str_ == NULL) return false;
+
+  const size_t this_len = strlen(c_str_);
+  const size_t suffix_len = strlen(suffix);
+  return (this_len >= suffix_len) &&
+         CStringEquals(c_str_ + this_len - suffix_len, suffix);
+}
+
+// Returns true iff this String ends with the given suffix, ignoring case.
+// Any String is considered to end with a NULL or empty suffix.
+bool String::EndsWithCaseInsensitive(const char* suffix) const {
+  if (suffix == NULL || CStringEquals(suffix, "")) return true;
+
+  if (c_str_ == NULL) return false;
+
+  const size_t this_len = strlen(c_str_);
+  const size_t suffix_len = strlen(suffix);
+  return (this_len >= suffix_len) &&
+         CaseInsensitiveCStringEquals(c_str_ + this_len - suffix_len, suffix);
+}
+
+// Sets the 0-terminated C string this String object represents.  The
+// old string in this object is deleted, and this object will own a
+// clone of the input string.  This function copies only up to length
+// bytes (plus a terminating null byte), or until the first null byte,
+// whichever comes first.
+//
+// This function works even when the c_str parameter has the same
+// value as that of the c_str_ field.
+void String::Set(const char * c_str, size_t length) {
+  // Makes sure this works when c_str == c_str_
+  const char* const temp = CloneString(c_str, length);
+  delete[] c_str_;
+  c_str_ = temp;
+}
+
+// Assigns a C string to this object.  Self-assignment works.
+const String& String::operator=(const char* c_str) {
+  // Makes sure this works when c_str == c_str_
+  if (c_str != c_str_) {
+    delete[] c_str_;
+    c_str_ = CloneCString(c_str);
+  }
+  return *this;
+}
+
+// Formats a list of arguments to a String, using the same format
+// spec string as for printf.
+//
+// We do not use the StringPrintf class as it is not universally
+// available.
+//
+// The result is limited to 4096 characters (including the tailing 0).
+// If 4096 characters are not enough to format the input,
+// "<buffer exceeded>" is returned.
+String String::Format(const char * format, ...) {
+  va_list args;
+  va_start(args, format);
+
+  char buffer[4096];
+  // MSVC 8 deprecates vsnprintf(), so we want to suppress warning
+  // 4996 (deprecated function) there.
+#ifdef GTEST_OS_WINDOWS  // We are on Windows.
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4996)  // Temporarily disables warning 4996.
+  const int size =
+    vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args);
+#pragma warning(pop)           // Restores the warning state.
+#else  // We are on Linux or Mac OS.
+  const int size =
+    vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args);
+#endif  // GTEST_OS_WINDOWS
+  va_end(args);
+
+  return String(size >= 0 ? buffer : "<buffer exceeded>");
+}
+
+// Converts the buffer in a StrStream to a String, converting NUL
+// bytes to "\\0" along the way.
+String StrStreamToString(StrStream* ss) {
+#if GTEST_HAS_STD_STRING
+  const ::std::string& str = ss->str();
+  const char* const start = str.c_str();
+  const char* const end = start + str.length();
+#else
+  const char* const start = ss->str();
+  const char* const end = start + ss->pcount();
+#endif  // GTEST_HAS_STD_STRING
+
+  // We need to use a helper StrStream to do this transformation
+  // because String doesn't support push_back().
+  StrStream helper;
+  for (const char* ch = start; ch != end; ++ch) {
+    if (*ch == '\0') {
+      helper << "\\0";  // Replaces NUL with "\\0";
+    } else {
+      helper.put(*ch);
+    }
+  }
+
+#if GTEST_HAS_STD_STRING
+  return String(helper.str().c_str());
+#else
+  const String str(helper.str(), helper.pcount());
+  helper.freeze(false);
+  ss->freeze(false);
+  return str;
+#endif  // GTEST_HAS_STD_STRING
+}
+
+// Appends the user-supplied message to the Google-Test-generated message.
+String AppendUserMessage(const String& gtest_msg,
+                         const Message& user_msg) {
+  // Appends the user message if it's non-empty.
+  const String user_msg_string = user_msg.GetString();
+  if (user_msg_string.empty()) {
+    return gtest_msg;
+  }
+
+  Message msg;
+  msg << gtest_msg << "\n" << user_msg_string;
+
+  return msg.GetString();
+}
+
+}  // namespace internal
+
+// Prints a TestPartResult object.
+std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
+  return os << result.file_name() << ":"
+            << result.line_number() << ": "
+            << (result.type() == TPRT_SUCCESS ? "Success" :
+                result.type() == TPRT_FATAL_FAILURE ? "Fatal failure" :
+                "Non-fatal failure") << ":\n"
+            << result.message() << std::endl;
+}
+
+namespace internal {
+// class TestResult
+
+// Creates an empty TestResult.
+TestResult::TestResult()
+    : death_test_count_(0),
+      elapsed_time_(0) {
+}
+
+// D'tor.
+TestResult::~TestResult() {
+}
+
+// Adds a test part result to the list.
+void TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
+  test_part_results_.PushBack(test_part_result);
+}
+
+// Adds a test property to the list. If a property with the same key as the
+// supplied property is already represented, the value of this test_property
+// replaces the old value for that key.
+void TestResult::RecordProperty(const TestProperty& test_property) {
+  if (!ValidateTestProperty(test_property)) {
+    return;
+  }
+  MutexLock lock(&test_properites_mutex_);
+  ListNode<TestProperty>* const node_with_matching_key =
+      test_properties_.FindIf(TestPropertyKeyIs(test_property.key()));
+  if (node_with_matching_key == NULL) {
+    test_properties_.PushBack(test_property);
+    return;
+  }
+  TestProperty& property_with_matching_key = node_with_matching_key->element();
+  property_with_matching_key.SetValue(test_property.value());
+}
+
+// Adds a failure if the key is a reserved attribute of Google Test testcase tags.
+// Returns true if the property is valid.
+bool TestResult::ValidateTestProperty(const TestProperty& test_property) {
+  String key(test_property.key());
+  if (key == "name" || key == "status" || key == "time" || key == "classname") {
+    ADD_FAILURE()
+        << "Reserved key used in RecordProperty(): "
+        << key
+        << " ('name', 'status', 'time', and 'classname' are reserved by "
+        << GTEST_NAME << ")";
+    return false;
+  }
+  return true;
+}
+
+// Clears the object.
+void TestResult::Clear() {
+  test_part_results_.Clear();
+  test_properties_.Clear();
+  death_test_count_ = 0;
+  elapsed_time_ = 0;
+}
+
+// Returns true iff the test part passed.
+static bool TestPartPassed(const TestPartResult & result) {
+  return result.passed();
+}
+
+// Gets the number of successful test parts.
+int TestResult::successful_part_count() const {
+  return test_part_results_.CountIf(TestPartPassed);
+}
+
+// Returns true iff the test part failed.
+static bool TestPartFailed(const TestPartResult & result) {
+  return result.failed();
+}
+
+// Gets the number of failed test parts.
+int TestResult::failed_part_count() const {
+  return test_part_results_.CountIf(TestPartFailed);
+}
+
+// Returns true iff the test part fatally failed.
+static bool TestPartFatallyFailed(const TestPartResult & result) {
+  return result.fatally_failed();
+}
+
+// Returns true iff the test fatally failed.
+bool TestResult::HasFatalFailure() const {
+  return test_part_results_.CountIf(TestPartFatallyFailed) > 0;
+}
+
+// Gets the number of all test parts.  This is the sum of the number
+// of successful test parts and the number of failed test parts.
+int TestResult::total_part_count() const {
+  return test_part_results_.size();
+}
+
+}  // namespace internal
+
+// class Test
+
+// Creates a Test object.
+
+// The c'tor saves the values of all Google Test flags.
+Test::Test()
+    : gtest_flag_saver_(new internal::GTestFlagSaver) {
+}
+
+// The d'tor restores the values of all Google Test flags.
+Test::~Test() {
+  delete gtest_flag_saver_;
+}
+
+// Sets up the test fixture.
+//
+// A sub-class may override this.
+void Test::SetUp() {
+}
+
+// Tears down the test fixture.
+//
+// A sub-class may override this.
+void Test::TearDown() {
+}
+
+// Allows user supplied key value pairs to be recorded for later output.
+void Test::RecordProperty(const char* key, const char* value) {
+  UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value);
+}
+
+// Allows user supplied key value pairs to be recorded for later output.
+void Test::RecordProperty(const char* key, int value) {
+  Message value_message;
+  value_message << value;
+  RecordProperty(key, value_message.GetString().c_str());
+}
+
+#ifdef GTEST_OS_WINDOWS
+// We are on Windows.
+
+// Adds an "exception thrown" fatal failure to the current test.
+static void AddExceptionThrownFailure(DWORD exception_code,
+                                      const char* location) {
+  Message message;
+  message << "Exception thrown with code 0x" << std::setbase(16) <<
+    exception_code << std::setbase(10) << " in " << location << ".";
+
+  UnitTest* const unit_test = UnitTest::GetInstance();
+  unit_test->AddTestPartResult(
+      TPRT_FATAL_FAILURE,
+      static_cast<const char *>(NULL),
+           // We have no info about the source file where the exception
+           // occurred.
+      -1,  // We have no info on which line caused the exception.
+      message.GetString(),
+      internal::String(""));
+}
+
+#endif  // GTEST_OS_WINDOWS
+
+// Google Test requires all tests in the same test case to use the same test
+// fixture class.  This function checks if the current test has the
+// same fixture class as the first test in the current test case.  If
+// yes, it returns true; otherwise it generates a Google Test failure and
+// returns false.
+bool Test::HasSameFixtureClass() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  const TestCase* const test_case = impl->current_test_case();
+
+  // Info about the first test in the current test case.
+  const internal::TestInfoImpl* const first_test_info =
+      test_case->test_info_list().Head()->element()->impl();
+  const internal::TypeId first_fixture_id = first_test_info->fixture_class_id();
+  const char* const first_test_name = first_test_info->name();
+
+  // Info about the current test.
+  const internal::TestInfoImpl* const this_test_info =
+      impl->current_test_info()->impl();
+  const internal::TypeId this_fixture_id = this_test_info->fixture_class_id();
+  const char* const this_test_name = this_test_info->name();
+
+  if (this_fixture_id != first_fixture_id) {
+    // Is the first test defined using TEST?
+    const bool first_is_TEST = first_fixture_id == internal::GetTypeId<Test>();
+    // Is this test defined using TEST?
+    const bool this_is_TEST = this_fixture_id == internal::GetTypeId<Test>();
+
+    if (first_is_TEST || this_is_TEST) {
+      // The user mixed TEST and TEST_F in this test case - we'll tell
+      // him/her how to fix it.
+
+      // Gets the name of the TEST and the name of the TEST_F.  Note
+      // that first_is_TEST and this_is_TEST cannot both be true, as
+      // the fixture IDs are different for the two tests.
+      const char* const TEST_name =
+          first_is_TEST ? first_test_name : this_test_name;
+      const char* const TEST_F_name =
+          first_is_TEST ? this_test_name : first_test_name;
+
+      ADD_FAILURE()
+          << "All tests in the same test case must use the same test fixture\n"
+          << "class, so mixing TEST_F and TEST in the same test case is\n"
+          << "illegal.  In test case " << this_test_info->test_case_name()
+          << ",\n"
+          << "test " << TEST_F_name << " is defined using TEST_F but\n"
+          << "test " << TEST_name << " is defined using TEST.  You probably\n"
+          << "want to change the TEST to TEST_F or move it to another test\n"
+          << "case.";
+    } else {
+      // The user defined two fixture classes with the same name in
+      // two namespaces - we'll tell him/her how to fix it.
+      ADD_FAILURE()
+          << "All tests in the same test case must use the same test fixture\n"
+          << "class.  However, in test case "
+          << this_test_info->test_case_name() << ",\n"
+          << "you defined test " << first_test_name
+          << " and test " << this_test_name << "\n"
+          << "using two different test fixture classes.  This can happen if\n"
+          << "the two classes are from different namespaces or translation\n"
+          << "units and have the same name.  You should probably rename one\n"
+          << "of the classes to put the tests into different test cases.";
+    }
+    return false;
+  }
+
+  return true;
+}
+
+// Runs the test and updates the test result.
+void Test::Run() {
+  if (!HasSameFixtureClass()) return;
+
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+#ifdef GTEST_OS_WINDOWS
+  // We are on Windows.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  __try {
+    SetUp();
+  } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+      GetExceptionCode())) {
+    AddExceptionThrownFailure(GetExceptionCode(), "SetUp()");
+  }
+
+  // We will run the test only if SetUp() had no fatal failure.
+  if (!HasFatalFailure()) {
+    impl->os_stack_trace_getter()->UponLeavingGTest();
+    __try {
+      TestBody();
+    } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+        GetExceptionCode())) {
+      AddExceptionThrownFailure(GetExceptionCode(), "the test body");
+    }
+  }
+
+  // However, we want to clean up as much as possible.  Hence we will
+  // always call TearDown(), even if SetUp() or the test body has
+  // failed.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  __try {
+    TearDown();
+  } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+      GetExceptionCode())) {
+    AddExceptionThrownFailure(GetExceptionCode(), "TearDown()");
+  }
+
+#else  // We are on Linux or Mac - exceptions are disabled.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  SetUp();
+
+  // We will run the test only if SetUp() was successful.
+  if (!HasFatalFailure()) {
+    impl->os_stack_trace_getter()->UponLeavingGTest();
+    TestBody();
+  }
+
+  // However, we want to clean up as much as possible.  Hence we will
+  // always call TearDown(), even if SetUp() or the test body has
+  // failed.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  TearDown();
+#endif  // GTEST_OS_WINDOWS
+}
+
+
+// Returns true iff the current test has a fatal failure.
+bool Test::HasFatalFailure() {
+  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();
+}
+
+// class TestInfo
+
+// Constructs a TestInfo object.
+TestInfo::TestInfo(const char* test_case_name,
+                   const char* name,
+                   internal::TypeId fixture_class_id,
+                   TestMaker maker) {
+  impl_ = new internal::TestInfoImpl(this, test_case_name, name,
+                                     fixture_class_id, maker);
+}
+
+// Destructs a TestInfo object.
+TestInfo::~TestInfo() {
+  delete impl_;
+}
+
+// Creates a TestInfo object and registers it with the UnitTest
+// singleton; returns the created object.
+//
+// Arguments:
+//
+//   test_case_name: name of the test case
+//   name:           name of the test
+//   set_up_tc:      pointer to the function that sets up the test case
+//   tear_down_tc:   pointer to the function that tears down the test case
+//   maker:          pointer to the function that creates a test object
+TestInfo* TestInfo::MakeAndRegisterInstance(
+    const char* test_case_name,
+    const char* name,
+    internal::TypeId fixture_class_id,
+    Test::SetUpTestCaseFunc set_up_tc,
+    Test::TearDownTestCaseFunc tear_down_tc,
+    TestMaker maker) {
+  TestInfo* const test_info =
+      new TestInfo(test_case_name, name, fixture_class_id, maker);
+  internal::GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
+  return test_info;
+}
+
+// Returns the test case name.
+const char* TestInfo::test_case_name() const {
+  return impl_->test_case_name();
+}
+
+// Returns the test name.
+const char* TestInfo::name() const {
+  return impl_->name();
+}
+
+// Returns true if this test should run.
+bool TestInfo::should_run() const { return impl_->should_run(); }
+
+// Returns the result of the test.
+const internal::TestResult* TestInfo::result() const { return impl_->result(); }
+
+// Increments the number of death tests encountered in this test so
+// far.
+int TestInfo::increment_death_test_count() {
+  return impl_->result()->increment_death_test_count();
+}
+
+namespace {
+
+// A predicate that checks the test name of a TestInfo against a known
+// value.
+//
+// This is used for implementation of the TestCase class only.  We put
+// it in the anonymous namespace to prevent polluting the outer
+// namespace.
+//
+// TestNameIs is copyable.
+class TestNameIs {
+ public:
+  // Constructor.
+  //
+  // TestNameIs has NO default constructor.
+  explicit TestNameIs(const char* name)
+      : name_(name) {}
+
+  // Returns true iff the test name of test_info matches name_.
+  bool operator()(const TestInfo * test_info) const {
+    return test_info && internal::String(test_info->name()).Compare(name_) == 0;
+  }
+
+ private:
+  internal::String name_;
+};
+
+}  // namespace
+
+// Finds and returns a TestInfo with the given name.  If one doesn't
+// exist, returns NULL.
+TestInfo * TestCase::GetTestInfo(const char* test_name) {
+  // Can we find a TestInfo with the given name?
+  internal::ListNode<TestInfo *> * const node = test_info_list_->FindIf(
+      TestNameIs(test_name));
+
+  // Returns the TestInfo found.
+  return node ? node->element() : NULL;
+}
+
+namespace internal {
+
+// Creates the test object, runs it, records its result, and then
+// deletes it.
+void TestInfoImpl::Run() {
+  if (!should_run_) return;
+
+  // Tells UnitTest where to store test result.
+  UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  impl->set_current_test_info(parent_);
+
+  // Notifies the unit test event listener that a test is about to
+  // start.
+  UnitTestEventListenerInterface* const result_printer =
+    impl->result_printer();
+  result_printer->OnTestStart(parent_);
+
+  const TimeInMillis start = GetTimeInMillis();
+
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+#ifdef GTEST_OS_WINDOWS
+  // We are on Windows.
+  Test* test = NULL;
+
+  __try {
+    // Creates the test object.
+    test = (*maker_)();
+  } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+      GetExceptionCode())) {
+    AddExceptionThrownFailure(GetExceptionCode(),
+                              "the test fixture's constructor");
+    return;
+  }
+#else  // We are on Linux or Mac OS - exceptions are disabled.
+
+  // TODO(wan): If test->Run() throws, test won't be deleted.  This is
+  // not a problem now as we don't use exceptions.  If we were to
+  // enable exceptions, we should revise the following to be
+  // exception-safe.
+
+  // Creates the test object.
+  Test* test = (*maker_)();
+#endif  // GTEST_OS_WINDOWS
+
+  // Runs the test only if the constructor of the test fixture didn't
+  // generate a fatal failure.
+  if (!Test::HasFatalFailure()) {
+    test->Run();
+  }
+
+  // Deletes the test object.
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  delete test;
+  test = NULL;
+
+  result_.set_elapsed_time(GetTimeInMillis() - start);
+
+  // Notifies the unit test event listener that a test has just finished.
+  result_printer->OnTestEnd(parent_);
+
+  // Tells UnitTest to stop associating assertion results to this
+  // test.
+  impl->set_current_test_info(NULL);
+}
+
+}  // namespace internal
+
+// class TestCase
+
+// Gets the number of successful tests in this test case.
+int TestCase::successful_test_count() const {
+  return test_info_list_->CountIf(TestPassed);
+}
+
+// Gets the number of failed tests in this test case.
+int TestCase::failed_test_count() const {
+  return test_info_list_->CountIf(TestFailed);
+}
+
+int TestCase::disabled_test_count() const {
+  return test_info_list_->CountIf(TestDisabled);
+}
+
+// Get the number of tests in this test case that should run.
+int TestCase::test_to_run_count() const {
+  return test_info_list_->CountIf(ShouldRunTest);
+}
+
+// Gets the number of all tests.
+int TestCase::total_test_count() const {
+  return test_info_list_->size();
+}
+
+// Creates a TestCase with the given name.
+//
+// Arguments:
+//
+//   name:         name of the test case
+//   set_up_tc:    pointer to the function that sets up the test case
+//   tear_down_tc: pointer to the function that tears down the test case
+TestCase::TestCase(const char* name,
+                   Test::SetUpTestCaseFunc set_up_tc,
+                   Test::TearDownTestCaseFunc tear_down_tc)
+    : name_(name),
+      set_up_tc_(set_up_tc),
+      tear_down_tc_(tear_down_tc),
+      should_run_(false),
+      elapsed_time_(0) {
+  test_info_list_ = new internal::List<TestInfo *>;
+}
+
+// Destructor of TestCase.
+TestCase::~TestCase() {
+  // Deletes every Test in the collection.
+  test_info_list_->ForEach(internal::Delete<TestInfo>);
+
+  // Then deletes the Test collection.
+  delete test_info_list_;
+  test_info_list_ = NULL;
+}
+
+// Adds a test to this test case.  Will delete the test upon
+// destruction of the TestCase object.
+void TestCase::AddTestInfo(TestInfo * test_info) {
+  test_info_list_->PushBack(test_info);
+}
+
+// Runs every test in this TestCase.
+void TestCase::Run() {
+  if (!should_run_) return;
+
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  impl->set_current_test_case(this);
+
+  UnitTestEventListenerInterface * const result_printer =
+      impl->result_printer();
+
+  result_printer->OnTestCaseStart(this);
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  set_up_tc_();
+
+  const internal::TimeInMillis start = internal::GetTimeInMillis();
+  test_info_list_->ForEach(internal::TestInfoImpl::RunTest);
+  elapsed_time_ = internal::GetTimeInMillis() - start;
+
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  tear_down_tc_();
+  result_printer->OnTestCaseEnd(this);
+  impl->set_current_test_case(NULL);
+}
+
+// Clears the results of all tests in this test case.
+void TestCase::ClearResult() {
+  test_info_list_->ForEach(internal::TestInfoImpl::ClearTestResult);
+}
+
+
+// class UnitTestEventListenerInterface
+
+// The virtual d'tor.
+UnitTestEventListenerInterface::~UnitTestEventListenerInterface() {
+}
+
+// A result printer that never prints anything.  Used in the child process
+// of an exec-style death test to avoid needless output clutter.
+class NullUnitTestResultPrinter : public UnitTestEventListenerInterface {};
+
+// Formats a countable noun.  Depending on its quantity, either the
+// singular form or the plural form is used. e.g.
+//
+// FormatCountableNoun(1, "formula", "formuli") returns "1 formula".
+// FormatCountableNoun(5, "book", "books") returns "5 books".
+static internal::String FormatCountableNoun(int count,
+                                            const char * singular_form,
+                                            const char * plural_form) {
+  return internal::String::Format("%d %s", count,
+                                  count == 1 ? singular_form : plural_form);
+}
+
+// Formats the count of tests.
+static internal::String FormatTestCount(int test_count) {
+  return FormatCountableNoun(test_count, "test", "tests");
+}
+
+// Formats the count of test cases.
+static internal::String FormatTestCaseCount(int test_case_count) {
+  return FormatCountableNoun(test_case_count, "test case", "test cases");
+}
+
+// Converts a TestPartResultType enum to human-friendly string
+// representation.  Both TPRT_NONFATAL_FAILURE and TPRT_FATAL_FAILURE
+// are translated to "Failure", as the user usually doesn't care about
+// the difference between the two when viewing the test result.
+static const char * TestPartResultTypeToString(TestPartResultType type) {
+  switch (type) {
+    case TPRT_SUCCESS:
+      return "Success";
+
+    case TPRT_NONFATAL_FAILURE:
+    case TPRT_FATAL_FAILURE:
+      return "Failure";
+  }
+
+  return "Unknown result type";
+}
+
+// Prints a TestPartResult.
+static void PrintTestPartResult(
+    const TestPartResult & test_part_result) {
+  const char * const file_name = test_part_result.file_name();
+
+  printf("%s", file_name == NULL ? "unknown file" : file_name);
+  if (test_part_result.line_number() >= 0) {
+    printf(":%d", test_part_result.line_number());
+  }
+  printf(": %s\n", TestPartResultTypeToString(test_part_result.type()));
+  printf("%s\n", test_part_result.message());
+  fflush(stdout);
+}
+
+// class PrettyUnitTestResultPrinter
+
+namespace internal {
+
+enum GTestColor {
+  COLOR_RED,
+  COLOR_GREEN,
+  COLOR_YELLOW
+};
+
+#ifdef _WIN32
+
+// Returns the character attribute for the given color.
+WORD GetColorAttribute(GTestColor color) {
+  switch (color) {
+    case COLOR_RED:    return FOREGROUND_RED;
+    case COLOR_GREEN:  return FOREGROUND_GREEN;
+    case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
+  }
+  return 0;
+}
+
+#else
+
+// Returns the ANSI color code for the given color.
+const char* GetAnsiColorCode(GTestColor color) {
+  switch (color) {
+    case COLOR_RED:     return "1";
+    case COLOR_GREEN:   return "2";
+    case COLOR_YELLOW:  return "3";
+  };
+  return NULL;
+}
+
+#endif  // _WIN32
+
+// Returns true iff Google Test should use colors in the output.
+bool ShouldUseColor(bool stdout_is_tty) {
+  const char* const gtest_color = GTEST_FLAG(color).c_str();
+
+  if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
+#ifdef _WIN32
+    // On Windows the TERM variable is usually not set, but the
+    // console there does support colors.
+    return stdout_is_tty;
+#else
+    // On non-Windows platforms, we rely on the TERM variable.
+    const char* const term = GetEnv("TERM");
+    const bool term_supports_color =
+        String::CStringEquals(term, "xterm") ||
+        String::CStringEquals(term, "xterm-color") ||
+        String::CStringEquals(term, "cygwin");
+    return stdout_is_tty && term_supports_color;
+#endif  // _WIN32
+  }
+
+  return String::CaseInsensitiveCStringEquals(gtest_color, "yes") ||
+      String::CaseInsensitiveCStringEquals(gtest_color, "true") ||
+      String::CaseInsensitiveCStringEquals(gtest_color, "t") ||
+      String::CStringEquals(gtest_color, "1");
+  // We take "yes", "true", "t", and "1" as meaning "yes".  If the
+  // value is neither one of these nor "auto", we treat it as "no" to
+  // be conservative.
+}
+
+// Helpers for printing colored strings to stdout. Note that on Windows, we
+// cannot simply emit special characters and have the terminal change colors.
+// This routine must actually emit the characters rather than return a string
+// that would be colored when printed, as can be done on Linux.
+void ColoredPrintf(GTestColor color, const char* fmt, ...) {
+  va_list args;
+  va_start(args, fmt);
+
+  static const bool use_color = ShouldUseColor(isatty(fileno(stdout)) != 0);
+  // The '!= 0' comparison is necessary to satisfy MSVC 7.1.
+
+  if (!use_color) {
+    vprintf(fmt, args);
+    va_end(args);
+    return;
+  }
+
+#ifdef _WIN32
+  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+
+  // Gets the current text color.
+  CONSOLE_SCREEN_BUFFER_INFO buffer_info;
+  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
+  const WORD old_color_attrs = buffer_info.wAttributes;
+
+  SetConsoleTextAttribute(stdout_handle,
+                          GetColorAttribute(color) | FOREGROUND_INTENSITY);
+  vprintf(fmt, args);
+
+  // Restores the text color.
+  SetConsoleTextAttribute(stdout_handle, old_color_attrs);
+#else
+  printf("\033[0;3%sm", GetAnsiColorCode(color));
+  vprintf(fmt, args);
+  printf("\033[m");  // Resets the terminal to default.
+#endif  // _WIN32
+  va_end(args);
+}
+
+}  // namespace internal
+
+using internal::ColoredPrintf;
+using internal::COLOR_RED;
+using internal::COLOR_GREEN;
+using internal::COLOR_YELLOW;
+
+// This class implements the UnitTestEventListenerInterface interface.
+//
+// Class PrettyUnitTestResultPrinter is copyable.
+class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface {
+ public:
+  PrettyUnitTestResultPrinter() {}
+  static void PrintTestName(const char * test_case, const char * test) {
+    printf("%s.%s", test_case, test);
+  }
+
+  // The following methods override what's in the
+  // UnitTestEventListenerInterface class.
+  virtual void OnUnitTestStart(const UnitTest * unit_test);
+  virtual void OnGlobalSetUpStart(const UnitTest*);
+  virtual void OnTestCaseStart(const TestCase * test_case);
+  virtual void OnTestStart(const TestInfo * test_info);
+  virtual void OnNewTestPartResult(const TestPartResult * result);
+  virtual void OnTestEnd(const TestInfo * test_info);
+  virtual void OnGlobalTearDownStart(const UnitTest*);
+  virtual void OnUnitTestEnd(const UnitTest * unit_test);
+
+ private:
+  internal::String test_case_name_;
+};
+
+// Called before the unit test starts.
+void PrettyUnitTestResultPrinter::OnUnitTestStart(
+    const UnitTest * unit_test) {
+  const char * const filter = GTEST_FLAG(filter).c_str();
+
+  // Prints the filter if it's not *.  This reminds the user that some
+  // tests may be skipped.
+  if (!internal::String::CStringEquals(filter, kUniversalFilter)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: %s filter = %s\n", GTEST_NAME, filter);
+  }
+
+  const internal::UnitTestImpl* const impl = unit_test->impl();
+  ColoredPrintf(COLOR_GREEN,  "[==========] ");
+  printf("Running %s from %s.\n",
+         FormatTestCount(impl->test_to_run_count()).c_str(),
+         FormatTestCaseCount(impl->test_case_to_run_count()).c_str());
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(const UnitTest*) {
+  ColoredPrintf(COLOR_GREEN,  "[----------] ");
+  printf("Global test environment set-up.\n");
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestCaseStart(
+    const TestCase * test_case) {
+  test_case_name_ = test_case->name();
+  const internal::String counts =
+      FormatCountableNoun(test_case->test_to_run_count(), "test", "tests");
+  ColoredPrintf(COLOR_GREEN, "[----------] ");
+  printf("%s from %s\n", counts.c_str(), test_case_name_.c_str());
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo * test_info) {
+  ColoredPrintf(COLOR_GREEN,  "[ RUN      ] ");
+  PrintTestName(test_case_name_.c_str(), test_info->name());
+  printf("\n");
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) {
+  if (test_info->result()->Passed()) {
+    ColoredPrintf(COLOR_GREEN, "[       OK ] ");
+  } else {
+    ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+  }
+  PrintTestName(test_case_name_.c_str(), test_info->name());
+  printf("\n");
+  fflush(stdout);
+}
+
+// Called after an assertion failure.
+void PrettyUnitTestResultPrinter::OnNewTestPartResult(
+    const TestPartResult * result) {
+  // If the test part succeeded, we don't need to do anything.
+  if (result->type() == TPRT_SUCCESS)
+    return;
+
+  // Print failure message from the assertion (e.g. expected this and got that).
+  PrintTestPartResult(*result);
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnGlobalTearDownStart(const UnitTest*) {
+  ColoredPrintf(COLOR_GREEN,  "[----------] ");
+  printf("Global test environment tear-down\n");
+  fflush(stdout);
+}
+
+namespace internal {
+
+// Internal helper for printing the list of failed tests.
+static void PrintFailedTestsPretty(const UnitTestImpl* impl) {
+  const int failed_test_count = impl->failed_test_count();
+  if (failed_test_count == 0) {
+    return;
+  }
+
+  for (const internal::ListNode<TestCase*>* node = impl->test_cases()->Head();
+       node != NULL; node = node->next()) {
+    const TestCase* const tc = node->element();
+    if (!tc->should_run() || (tc->failed_test_count() == 0)) {
+      continue;
+    }
+    for (const internal::ListNode<TestInfo*>* tinode =
+         tc->test_info_list().Head();
+         tinode != NULL; tinode = tinode->next()) {
+      const TestInfo* const ti = tinode->element();
+      if (!tc->ShouldRunTest(ti) || tc->TestPassed(ti)) {
+        continue;
+      }
+      ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+      printf("%s.%s\n", ti->test_case_name(), ti->name());
+    }
+  }
+}
+
+}  // namespace internal
+
+void PrettyUnitTestResultPrinter::OnUnitTestEnd(
+    const UnitTest * unit_test) {
+  const internal::UnitTestImpl* const impl = unit_test->impl();
+
+  ColoredPrintf(COLOR_GREEN,  "[==========] ");
+  printf("%s from %s ran.\n",
+         FormatTestCount(impl->test_to_run_count()).c_str(),
+         FormatTestCaseCount(impl->test_case_to_run_count()).c_str());
+  ColoredPrintf(COLOR_GREEN,  "[  PASSED  ] ");
+  printf("%s.\n", FormatTestCount(impl->successful_test_count()).c_str());
+
+  int num_failures = impl->failed_test_count();
+  if (!impl->Passed()) {
+    const int failed_test_count = impl->failed_test_count();
+    ColoredPrintf(COLOR_RED,  "[  FAILED  ] ");
+    printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str());
+    internal::PrintFailedTestsPretty(impl);
+    printf("\n%2d FAILED %s\n", num_failures,
+                        num_failures == 1 ? "TEST" : "TESTS");
+  }
+
+  int num_disabled = impl->disabled_test_count();
+  if (num_disabled) {
+    if (!num_failures) {
+      printf("\n");  // Add a spacer if no FAILURE banner is displayed.
+    }
+    ColoredPrintf(COLOR_YELLOW,
+                  "  YOU HAVE %d DISABLED %s\n\n",
+                  num_disabled,
+                  num_disabled == 1 ? "TEST" : "TESTS");
+  }
+  // Ensure that Google Test output is printed before, e.g., heapchecker output.
+  fflush(stdout);
+}
+
+// End PrettyUnitTestResultPrinter
+
+// class UnitTestEventsRepeater
+//
+// This class forwards events to other event listeners.
+class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
+ public:
+  typedef internal::List<UnitTestEventListenerInterface *> Listeners;
+  typedef internal::ListNode<UnitTestEventListenerInterface *> ListenersNode;
+  UnitTestEventsRepeater() {}
+  virtual ~UnitTestEventsRepeater();
+  void AddListener(UnitTestEventListenerInterface *listener);
+
+  virtual void OnUnitTestStart(const UnitTest* unit_test);
+  virtual void OnUnitTestEnd(const UnitTest* unit_test);
+  virtual void OnGlobalSetUpStart(const UnitTest* unit_test);
+  virtual void OnGlobalSetUpEnd(const UnitTest* unit_test);
+  virtual void OnGlobalTearDownStart(const UnitTest* unit_test);
+  virtual void OnGlobalTearDownEnd(const UnitTest* unit_test);
+  virtual void OnTestCaseStart(const TestCase* test_case);
+  virtual void OnTestCaseEnd(const TestCase* test_case);
+  virtual void OnTestStart(const TestInfo* test_info);
+  virtual void OnTestEnd(const TestInfo* test_info);
+  virtual void OnNewTestPartResult(const TestPartResult* result);
+
+ private:
+  Listeners listeners_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(UnitTestEventsRepeater);
+};
+
+UnitTestEventsRepeater::~UnitTestEventsRepeater() {
+  for (ListenersNode* listener = listeners_.Head();
+       listener != NULL;
+       listener = listener->next()) {
+    delete listener->element();
+  }
+}
+
+void UnitTestEventsRepeater::AddListener(
+    UnitTestEventListenerInterface *listener) {
+  listeners_.PushBack(listener);
+}
+
+// Since the methods are identical, use a macro to reduce boilerplate.
+// This defines a member that repeats the call to all listeners.
+#define GTEST_REPEATER_METHOD(Name, Type) \
+void UnitTestEventsRepeater::Name(const Type* parameter) { \
+  for (ListenersNode* listener = listeners_.Head(); \
+       listener != NULL; \
+       listener = listener->next()) { \
+    listener->element()->Name(parameter); \
+  } \
+}
+
+GTEST_REPEATER_METHOD(OnUnitTestStart, UnitTest)
+GTEST_REPEATER_METHOD(OnUnitTestEnd, UnitTest)
+GTEST_REPEATER_METHOD(OnGlobalSetUpStart, UnitTest)
+GTEST_REPEATER_METHOD(OnGlobalSetUpEnd, UnitTest)
+GTEST_REPEATER_METHOD(OnGlobalTearDownStart, UnitTest)
+GTEST_REPEATER_METHOD(OnGlobalTearDownEnd, UnitTest)
+GTEST_REPEATER_METHOD(OnTestCaseStart, TestCase)
+GTEST_REPEATER_METHOD(OnTestCaseEnd, TestCase)
+GTEST_REPEATER_METHOD(OnTestStart, TestInfo)
+GTEST_REPEATER_METHOD(OnTestEnd, TestInfo)
+GTEST_REPEATER_METHOD(OnNewTestPartResult, TestPartResult)
+
+#undef GTEST_REPEATER_METHOD
+
+// End PrettyUnitTestResultPrinter
+
+// This class generates an XML output file.
+class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface {
+ public:
+  explicit XmlUnitTestResultPrinter(const char* output_file);
+
+  virtual void OnUnitTestEnd(const UnitTest* unit_test);
+
+ private:
+  // Is c a whitespace character that is normalized to a space character
+  // when it appears in an XML attribute value?
+  static bool IsNormalizableWhitespace(char c) {
+    return c == 0x9 || c == 0xA || c == 0xD;
+  }
+
+  // May c appear in a well-formed XML document?
+  static bool IsValidXmlCharacter(char c) {
+    return IsNormalizableWhitespace(c) || c >= 0x20;
+  }
+
+  // Returns an XML-escaped copy of the input string str.  If
+  // is_attribute is true, the text is meant to appear as an attribute
+  // value, and normalizable whitespace is preserved by replacing it
+  // with character references.
+  static internal::String EscapeXml(const char* str,
+                                    bool is_attribute);
+
+  // Convenience wrapper around EscapeXml when str is an attribute value.
+  static internal::String EscapeXmlAttribute(const char* str) {
+    return EscapeXml(str, true);
+  }
+
+  // Convenience wrapper around EscapeXml when str is not an attribute value.
+  static internal::String EscapeXmlText(const char* str) {
+    return EscapeXml(str, false);
+  }
+
+  // Prints an XML representation of a TestInfo object.
+  static void PrintXmlTestInfo(FILE* out,
+                               const char* test_case_name,
+                               const TestInfo* test_info);
+
+  // Prints an XML representation of a TestCase object
+  static void PrintXmlTestCase(FILE* out, const TestCase* test_case);
+
+  // Prints an XML summary of unit_test to output stream out.
+  static void PrintXmlUnitTest(FILE* out, const UnitTest* unit_test);
+
+  // Produces a string representing the test properties in a result as space
+  // delimited XML attributes based on the property key="value" pairs.
+  // When the String is not empty, it includes a space at the beginning,
+  // to delimit this attribute from prior attributes.
+  static internal::String TestPropertiesAsXmlAttributes(
+      const internal::TestResult* result);
+
+  // The output file.
+  const internal::String output_file_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(XmlUnitTestResultPrinter);
+};
+
+// Creates a new XmlUnitTestResultPrinter.
+XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
+    : output_file_(output_file) {
+  if (output_file_.c_str() == NULL || output_file_.empty()) {
+    fprintf(stderr, "XML output file may not be null\n");
+    fflush(stderr);
+    exit(EXIT_FAILURE);
+  }
+}
+
+// Called after the unit test ends.
+void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest* unit_test) {
+  FILE* xmlout = NULL;
+  internal::FilePath output_file(output_file_);
+  internal::FilePath output_dir(output_file.RemoveFileName());
+
+  if (output_dir.CreateDirectoriesRecursively()) {
+  // MSVC 8 deprecates fopen(), so we want to suppress warning 4996
+  // (deprecated function) there.
+#ifdef GTEST_OS_WINDOWS
+  // We are on Windows.
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4996)  // Temporarily disables warning 4996.
+    xmlout = fopen(output_file_.c_str(), "w");
+#pragma warning(pop)           // Restores the warning state.
+#else  // We are on Linux or Mac OS.
+    xmlout = fopen(output_file_.c_str(), "w");
+#endif  // GTEST_OS_WINDOWS
+  }
+  if (xmlout == NULL) {
+    // TODO(wan): report the reason of the failure.
+    //
+    // We don't do it for now as:
+    //
+    //   1. There is no urgent need for it.
+    //   2. It's a bit involved to make the errno variable thread-safe on
+    //      all three operating systems (Linux, Windows, and Mac OS).
+    //   3. To interpret the meaning of errno in a thread-safe way,
+    //      we need the strerror_r() function, which is not available on
+    //      Windows.
+    fprintf(stderr,
+            "Unable to open file \"%s\"\n",
+            output_file_.c_str());
+    fflush(stderr);
+    exit(EXIT_FAILURE);
+  }
+  PrintXmlUnitTest(xmlout, unit_test);
+  fclose(xmlout);
+}
+
+// Returns an XML-escaped copy of the input string str.  If is_attribute
+// is true, the text is meant to appear as an attribute value, and
+// normalizable whitespace is preserved by replacing it with character
+// references.
+//
+// Invalid XML characters in str, if any, are stripped from the output.
+// It is expected that most, if not all, of the text processed by this
+// module will consist of ordinary English text.
+// If this module is ever modified to produce version 1.1 XML output,
+// most invalid characters can be retained using character references.
+// TODO(wan): It might be nice to have a minimally invasive, human-readable
+// escaping scheme for invalid characters, rather than dropping them.
+internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str,
+                                                     bool is_attribute) {
+  Message m;
+
+  if (str != NULL) {
+    for (const char* src = str; *src; ++src) {
+      switch (*src) {
+        case '<':
+          m << "&lt;";
+          break;
+        case '>':
+          m << "&gt;";
+          break;
+        case '&':
+          m << "&amp;";
+          break;
+        case '\'':
+          if (is_attribute)
+            m << "&apos;";
+          else
+            m << '\'';
+          break;
+        case '"':
+          if (is_attribute)
+            m << "&quot;";
+          else
+            m << '"';
+          break;
+        default:
+          if (IsValidXmlCharacter(*src)) {
+            if (is_attribute && IsNormalizableWhitespace(*src))
+              m << internal::String::Format("&#x%02X;", unsigned(*src));
+            else
+              m << *src;
+          }
+          break;
+      }
+    }
+  }
+
+  return m.GetString();
+}
+
+
+// The following routines generate an XML representation of a UnitTest
+// object.
+//
+// This is how Google Test concepts map to the DTD:
+//
+// <testsuite name="AllTests">         <-- corresponds to a UnitTest object
+//   <testsuite name="testcase-name">  <-- corresponds to a TestCase object
+//     <testcase name="test-name">     <-- corresponds to a TestInfo object
+//       <failure message="..." />
+//       <failure message="..." />     <-- individual assertion failures
+//       <failure message="..." />
+//     </testcase>
+//   </testsuite>
+// </testsuite>
+
+// Prints an XML representation of a TestInfo object.
+// TODO(wan): There is also value in printing properties with the plain printer.
+void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out,
+                                                const char* test_case_name,
+                                                const TestInfo* test_info) {
+  const internal::TestResult * const result = test_info->result();
+  const internal::List<TestPartResult> &results = result->test_part_results();
+  fprintf(out,
+          "    <testcase name=\"%s\" status=\"%s\" time=\"%s\" "
+          "classname=\"%s\"%s",
+          EscapeXmlAttribute(test_info->name()).c_str(),
+          test_info->should_run() ? "run" : "notrun",
+          internal::StreamableToString(result->elapsed_time()).c_str(),
+          EscapeXmlAttribute(test_case_name).c_str(),
+          TestPropertiesAsXmlAttributes(result).c_str());
+
+  int failures = 0;
+  for (const internal::ListNode<TestPartResult>* part_node = results.Head();
+       part_node != NULL;
+       part_node = part_node->next()) {
+    const TestPartResult& part = part_node->element();
+    if (part.failed()) {
+      const internal::String message =
+          internal::String::Format("%s:%d\n%s", part.file_name(),
+                                   part.line_number(), part.message());
+      if (++failures == 1)
+        fprintf(out, ">\n");
+      fprintf(out,
+              "      <failure message=\"%s\" type=\"\"/>\n",
+              EscapeXmlAttribute(message.c_str()).c_str());
+    }
+  }
+
+  if (failures == 0)
+    fprintf(out, " />\n");
+  else
+    fprintf(out, "    </testcase>\n");
+}
+
+// Prints an XML representation of a TestCase object
+void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
+                                                const TestCase* test_case) {
+  fprintf(out,
+          "  <testsuite name=\"%s\" tests=\"%d\" failures=\"%d\" "
+          "disabled=\"%d\" ",
+          EscapeXmlAttribute(test_case->name()).c_str(),
+          test_case->total_test_count(),
+          test_case->failed_test_count(),
+          test_case->disabled_test_count());
+  fprintf(out,
+          "errors=\"0\" time=\"%s\">\n",
+          internal::StreamableToString(test_case->elapsed_time()).c_str());
+  for (const internal::ListNode<TestInfo*>* info_node =
+         test_case->test_info_list().Head();
+       info_node != NULL;
+       info_node = info_node->next()) {
+    PrintXmlTestInfo(out, test_case->name(), info_node->element());
+  }
+  fprintf(out, "  </testsuite>\n");
+}
+
+// Prints an XML summary of unit_test to output stream out.
+void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
+                                                const UnitTest* unit_test) {
+  const internal::UnitTestImpl* const impl = unit_test->impl();
+  fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+  fprintf(out,
+          "<testsuite tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
+          "errors=\"0\" time=\"%s\" ",
+          impl->total_test_count(),
+          impl->failed_test_count(),
+          impl->disabled_test_count(),
+          internal::StreamableToString(impl->elapsed_time()).c_str());
+  fprintf(out, "name=\"AllTests\">\n");
+  for (const internal::ListNode<TestCase*>* case_node =
+       impl->test_cases()->Head();
+       case_node != NULL;
+       case_node = case_node->next()) {
+    PrintXmlTestCase(out, case_node->element());
+  }
+  fprintf(out, "</testsuite>\n");
+}
+
+// Produces a string representing the test properties in a result as space
+// delimited XML attributes based on the property key="value" pairs.
+internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
+    const internal::TestResult* result) {
+  using internal::TestProperty;
+  Message attributes;
+  const internal::List<TestProperty>& properties = result->test_properties();
+  for (const internal::ListNode<TestProperty>* property_node =
+       properties.Head();
+       property_node != NULL;
+       property_node = property_node->next()) {
+    const TestProperty& property = property_node->element();
+    attributes << " " << property.key() << "="
+        << "\"" << EscapeXmlAttribute(property.value()) << "\"";
+  }
+  return attributes.GetString();
+}
+
+// End XmlUnitTestResultPrinter
+
+namespace internal {
+
+// Class ScopedTrace
+
+// Pushes the given source file location and message onto a per-thread
+// trace stack maintained by Google Test.
+// L < UnitTest::mutex_
+ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) {
+  TraceInfo trace;
+  trace.file = file;
+  trace.line = line;
+  trace.message = message.GetString();
+
+  UnitTest::GetInstance()->PushGTestTrace(trace);
+}
+
+// Pops the info pushed by the c'tor.
+// L < UnitTest::mutex_
+ScopedTrace::~ScopedTrace() {
+  UnitTest::GetInstance()->PopGTestTrace();
+}
+
+
+// class OsStackTraceGetter
+
+// Returns the current OS stack trace as a String.  Parameters:
+//
+//   max_depth  - the maximum number of stack frames to be included
+//                in the trace.
+//   skip_count - the number of top frames to be skipped; doesn't count
+//                against max_depth.
+//
+// L < mutex_
+// We use "L < mutex_" to denote that the function may acquire mutex_.
+String OsStackTraceGetter::CurrentStackTrace(int, int) {
+  return String("");
+}
+
+// L < mutex_
+void OsStackTraceGetter::UponLeavingGTest() {
+}
+
+const char* const
+OsStackTraceGetter::kElidedFramesMarker =
+    "... " GTEST_NAME " internal frames ...";
+
+}  // namespace internal
+
+// class UnitTest
+
+// Gets the singleton UnitTest object.  The first time this method is
+// called, a UnitTest object is constructed and returned.  Consecutive
+// calls will return the same object.
+//
+// We don't protect this under mutex_ as a user is not supposed to
+// call this before main() starts, from which point on the return
+// value will never change.
+UnitTest * UnitTest::GetInstance() {
+  // When compiled with MSVC 7.1 in optimized mode, destroying the
+  // UnitTest object upon exiting the program messes up the exit code,
+  // causing successful tests to appear failed.  We have to use a
+  // different implementation in this case to bypass the compiler bug.
+  // This implementation makes the compiler happy, at the cost of
+  // leaking the UnitTest object.
+#if _MSC_VER == 1310 && !defined(_DEBUG)  // MSVC 7.1 and optimized build.
+  static UnitTest* const instance = new UnitTest;
+  return instance;
+#else
+  static UnitTest instance;
+  return &instance;
+#endif  // _MSC_VER==1310 && !defined(_DEBUG)
+}
+
+// Registers and returns a global test environment.  When a test
+// program is run, all global test environments will be set-up in the
+// order they were registered.  After all tests in the program have
+// finished, all global test environments will be torn-down in the
+// *reverse* order they were registered.
+//
+// The UnitTest object takes ownership of the given environment.
+//
+// We don't protect this under mutex_, as we only support calling it
+// from the main thread.
+Environment* UnitTest::AddEnvironment(Environment* env) {
+  if (env == NULL) {
+    return NULL;
+  }
+
+  impl_->environments()->PushBack(env);
+  impl_->environments_in_reverse_order()->PushFront(env);
+  return env;
+}
+
+// Adds a TestPartResult to the current TestResult object.  All Google Test
+// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call
+// this to report their results.  The user code should use the
+// assertion macros instead of calling this directly.
+// L < mutex_
+void UnitTest::AddTestPartResult(TestPartResultType result_type,
+                                 const char* file_name,
+                                 int line_number,
+                                 const internal::String& message,
+                                 const internal::String& os_stack_trace) {
+  Message msg;
+  msg << message;
+
+  internal::MutexLock lock(&mutex_);
+  if (impl_->gtest_trace_stack()->size() > 0) {
+    msg << "\n" << GTEST_NAME << " trace:";
+
+    for (internal::ListNode<internal::TraceInfo>* node =
+         impl_->gtest_trace_stack()->Head();
+         node != NULL;
+         node = node->next()) {
+      const internal::TraceInfo& trace = node->element();
+      msg << "\n" << trace.file << ":" << trace.line << ": " << trace.message;
+    }
+  }
+
+  if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {
+    msg << "\nStack trace:\n" << os_stack_trace;
+  }
+
+  const TestPartResult result =
+    TestPartResult(result_type, file_name, line_number,
+                   msg.GetString().c_str());
+  impl_->test_part_result_reporter()->ReportTestPartResult(result);
+
+  // If this is a failure and the user wants the debugger to break on
+  // failures ...
+  if (result_type != TPRT_SUCCESS && GTEST_FLAG(break_on_failure)) {
+    // ... then we generate a seg fault.
+    *static_cast<int*>(NULL) = 1;
+  }
+}
+
+// Creates and adds a property to the current TestResult. If a property matching
+// the supplied value already exists, updates its value instead.
+void UnitTest::RecordPropertyForCurrentTest(const char* key,
+                                            const char* value) {
+  const internal::TestProperty test_property(key, value);
+  impl_->current_test_result()->RecordProperty(test_property);
+}
+
+// Runs all tests in this UnitTest object and prints the result.
+// Returns 0 if successful, or 1 otherwise.
+//
+// We don't protect this under mutex_, as we only support calling it
+// from the main thread.
+int UnitTest::Run() {
+#ifdef GTEST_OS_WINDOWS
+
+#if !defined(_WIN32_WCE)
+  // SetErrorMode doesn't exist on CE.
+  if (GTEST_FLAG(catch_exceptions)) {
+    // The user wants Google Test to catch exceptions thrown by the tests.
+
+    // This lets fatal errors be handled by us, instead of causing pop-ups.
+    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
+                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
+  }
+#endif  // _WIN32_WCE
+
+  __try {
+    return impl_->RunAllTests();
+  } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+      GetExceptionCode())) {
+    printf("Exception thrown with code 0x%x.\nFAIL\n", GetExceptionCode());
+    fflush(stdout);
+    return 1;
+  }
+
+#else
+  // We are on Linux or Mac OS.  There is no exception of any kind.
+
+  return impl_->RunAllTests();
+#endif  // GTEST_OS_WINDOWS
+}
+
+// Returns the TestCase object for the test that's currently running,
+// or NULL if no test is running.
+// L < mutex_
+const TestCase* UnitTest::current_test_case() const {
+  internal::MutexLock lock(&mutex_);
+  return impl_->current_test_case();
+}
+
+// Returns the TestInfo object for the test that's currently running,
+// or NULL if no test is running.
+// L < mutex_
+const TestInfo* UnitTest::current_test_info() const {
+  internal::MutexLock lock(&mutex_);
+  return impl_->current_test_info();
+}
+
+// Creates an empty UnitTest.
+UnitTest::UnitTest() {
+  impl_ = new internal::UnitTestImpl(this);
+}
+
+// Destructor of UnitTest.
+UnitTest::~UnitTest() {
+  delete impl_;
+}
+
+// Pushes a trace defined by SCOPED_TRACE() on to the per-thread
+// Google Test trace stack.
+// L < mutex_
+void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) {
+  internal::MutexLock lock(&mutex_);
+  impl_->gtest_trace_stack()->PushFront(trace);
+}
+
+// Pops a trace from the per-thread Google Test trace stack.
+// L < mutex_
+void UnitTest::PopGTestTrace() {
+  internal::MutexLock lock(&mutex_);
+  impl_->gtest_trace_stack()->PopFront(NULL);
+}
+
+namespace internal {
+
+UnitTestImpl::UnitTestImpl(UnitTest* parent)
+    : parent_(parent),
+      test_cases_(),
+      last_death_test_case_(NULL),
+      current_test_case_(NULL),
+      current_test_info_(NULL),
+      ad_hoc_test_result_(),
+      result_printer_(NULL),
+      os_stack_trace_getter_(NULL),
+#ifdef GTEST_HAS_DEATH_TEST
+      elapsed_time_(0),
+      internal_run_death_test_flag_(NULL),
+      death_test_factory_(new DefaultDeathTestFactory) {
+#else
+      elapsed_time_(0) {
+#endif  // GTEST_HAS_DEATH_TEST
+  // We do the assignment here instead of in the initializer list, as
+  // doing that latter causes MSVC to issue a warning about using
+  // 'this' in initializers.
+  test_part_result_reporter_ = this;
+}
+
+UnitTestImpl::~UnitTestImpl() {
+  // Deletes every TestCase.
+  test_cases_.ForEach(internal::Delete<TestCase>);
+
+  // Deletes every Environment.
+  environments_.ForEach(internal::Delete<Environment>);
+
+  // Deletes the current test result printer.
+  delete result_printer_;
+
+  delete os_stack_trace_getter_;
+}
+
+// A predicate that checks the name of a TestCase against a known
+// value.
+//
+// This is used for implementation of the UnitTest class only.  We put
+// it in the anonymous namespace to prevent polluting the outer
+// namespace.
+//
+// TestCaseNameIs is copyable.
+class TestCaseNameIs {
+ public:
+  // Constructor.
+  explicit TestCaseNameIs(const String& name)
+      : name_(name) {}
+
+  // Returns true iff the name of test_case matches name_.
+  bool operator()(const TestCase* test_case) const {
+    return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0;
+  }
+
+ private:
+  String name_;
+};
+
+// Finds and returns a TestCase with the given name.  If one doesn't
+// exist, creates one and returns it.
+//
+// Arguments:
+//
+//   test_case_name: name of the test case
+//   set_up_tc:      pointer to the function that sets up the test case
+//   tear_down_tc:   pointer to the function that tears down the test case
+TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
+                                    Test::SetUpTestCaseFunc set_up_tc,
+                                    Test::TearDownTestCaseFunc tear_down_tc) {
+  // Can we find a TestCase with the given name?
+  internal::ListNode<TestCase*>* node = test_cases_.FindIf(
+      TestCaseNameIs(test_case_name));
+
+  if (node == NULL) {
+    // No.  Let's create one.
+    TestCase* const test_case =
+      new TestCase(test_case_name, set_up_tc, tear_down_tc);
+
+    // Is this a death test case?
+    if (String(test_case_name).EndsWith("DeathTest")) {
+      // Yes.  Inserts the test case after the last death test case
+      // defined so far.
+      node = test_cases_.InsertAfter(last_death_test_case_, test_case);
+      last_death_test_case_ = node;
+    } else {
+      // No.  Appends to the end of the list.
+      test_cases_.PushBack(test_case);
+      node = test_cases_.Last();
+    }
+  }
+
+  // Returns the TestCase found.
+  return node->element();
+}
+
+// Helpers for setting up / tearing down the given environment.  They
+// are for use in the List::ForEach() method.
+static void SetUpEnvironment(Environment* env) { env->SetUp(); }
+static void TearDownEnvironment(Environment* env) { env->TearDown(); }
+
+// Runs all tests in this UnitTest object, prints the result, and
+// returns 0 if all tests are successful, or 1 otherwise.  If any
+// exception is thrown during a test on Windows, this test is
+// considered to be failed, but the rest of the tests will still be
+// run.  (We disable exceptions on Linux and Mac OS X, so the issue
+// doesn't apply there.)
+int UnitTestImpl::RunAllTests() {
+  // True iff Google Test is initialized before RUN_ALL_TESTS() is called.
+  const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();
+
+  // Lists all the tests and exits if the --gtest_list_tests
+  // flag was specified.
+  if (GTEST_FLAG(list_tests)) {
+    ListAllTests();
+    return 0;
+  }
+
+  // True iff we are in a subprocess for running a thread-safe-style
+  // death test.
+  bool in_subprocess_for_death_test = false;
+
+#ifdef GTEST_HAS_DEATH_TEST
+  internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
+  in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
+#endif  // GTEST_HAS_DEATH_TEST
+
+  UnitTestEventListenerInterface * const printer = result_printer();
+
+  // Compares the full test names with the filter to decide which
+  // tests to run.
+  const bool has_tests_to_run = FilterTests() > 0;
+  // True iff at least one test has failed.
+  bool failed = false;
+
+  // How many times to repeat the tests?  We don't want to repeat them
+  // when we are inside the subprocess of a death test.
+  const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
+  // Repeats forever if the repeat count is negative.
+  const bool forever = repeat < 0;
+  for (int i = 0; forever || i != repeat; i++) {
+    if (repeat != 1) {
+      printf("\nRepeating all tests (iteration %d) . . .\n\n", i + 1);
+    }
+
+    // Tells the unit test event listener that the tests are about to
+    // start.
+    printer->OnUnitTestStart(parent_);
+
+    const TimeInMillis start = GetTimeInMillis();
+
+    // Runs each test case if there is at least one test to run.
+    if (has_tests_to_run) {
+      // Sets up all environments beforehand.
+      printer->OnGlobalSetUpStart(parent_);
+      environments_.ForEach(SetUpEnvironment);
+      printer->OnGlobalSetUpEnd(parent_);
+
+      // Runs the tests only if there was no fatal failure during global
+      // set-up.
+      if (!Test::HasFatalFailure()) {
+        test_cases_.ForEach(TestCase::RunTestCase);
+      }
+
+      // Tears down all environments in reverse order afterwards.
+      printer->OnGlobalTearDownStart(parent_);
+      environments_in_reverse_order_.ForEach(TearDownEnvironment);
+      printer->OnGlobalTearDownEnd(parent_);
+    }
+
+    elapsed_time_ = GetTimeInMillis() - start;
+
+    // Tells the unit test event listener that the tests have just
+    // finished.
+    printer->OnUnitTestEnd(parent_);
+
+    // Gets the result and clears it.
+    if (!Passed()) {
+      failed = true;
+    }
+    ClearResult();
+  }
+
+  if (!gtest_is_initialized_before_run_all_tests) {
+    ColoredPrintf(
+        COLOR_RED, "\nIMPORTANT NOTICE - DO NOT IGNORE:\n"
+        "This test program did NOT call %s() before calling RUN_ALL_TESTS(). "
+        "This is INVALID. Soon " GTEST_NAME
+        " will start to enforce the valid usage. "
+        "Please fix it ASAP, or IT WILL START TO FAIL.\n",
+        "testing::ParseGTestFlags"
+        );  // NOLINT
+  }
+
+  // Returns 0 if all tests passed, or 1 other wise.
+  return failed ? 1 : 0;
+}
+
+// Compares the name of each test with the user-specified filter to
+// decide whether the test should be run, then records the result in
+// each TestCase and TestInfo object.
+// Returns the number of tests that should run.
+int UnitTestImpl::FilterTests() {
+  int num_runnable_tests = 0;
+  for (const internal::ListNode<TestCase *> *test_case_node =
+       test_cases_.Head();
+       test_case_node != NULL;
+       test_case_node = test_case_node->next()) {
+    TestCase * const test_case = test_case_node->element();
+    const String &test_case_name = test_case->name();
+    test_case->set_should_run(false);
+
+    for (const internal::ListNode<TestInfo *> *test_info_node =
+           test_case->test_info_list().Head();
+         test_info_node != NULL;
+         test_info_node = test_info_node->next()) {
+      TestInfo * const test_info = test_info_node->element();
+      const String test_name(test_info->name());
+      // A test is disabled if test case name or test name matches
+      // kDisableTestPattern.
+      const bool is_disabled =
+        internal::UnitTestOptions::PatternMatchesString(kDisableTestPattern,
+            test_case_name.c_str()) ||
+        internal::UnitTestOptions::PatternMatchesString(kDisableTestPattern,
+            test_name.c_str());
+      test_info->impl()->set_is_disabled(is_disabled);
+
+      const bool should_run = !is_disabled &&
+          internal::UnitTestOptions::FilterMatchesTest(test_case_name,
+                                                       test_name);
+      test_info->impl()->set_should_run(should_run);
+      test_case->set_should_run(test_case->should_run() || should_run);
+      if (should_run) {
+        num_runnable_tests++;
+      }
+    }
+  }
+  return num_runnable_tests;
+}
+
+// Lists all tests by name.
+void UnitTestImpl::ListAllTests() {
+  for (const internal::ListNode<TestCase*>* test_case_node = test_cases_.Head();
+       test_case_node != NULL;
+       test_case_node = test_case_node->next()) {
+    const TestCase* const test_case = test_case_node->element();
+
+    // Prints the test case name following by an indented list of test nodes.
+    printf("%s.\n", test_case->name());
+
+    for (const internal::ListNode<TestInfo*>* test_info_node =
+         test_case->test_info_list().Head();
+         test_info_node != NULL;
+         test_info_node = test_info_node->next()) {
+      const TestInfo* const test_info = test_info_node->element();
+
+      printf("  %s\n", test_info->name());
+    }
+  }
+  fflush(stdout);
+}
+
+// Sets the unit test result printer.
+//
+// Does nothing if the input and the current printer object are the
+// same; otherwise, deletes the old printer object and makes the
+// input the current printer.
+void UnitTestImpl::set_result_printer(
+    UnitTestEventListenerInterface* result_printer) {
+  if (result_printer_ != result_printer) {
+    delete result_printer_;
+    result_printer_ = result_printer;
+  }
+}
+
+// Returns the current unit test result printer if it is not NULL;
+// otherwise, creates an appropriate result printer, makes it the
+// current printer, and returns it.
+UnitTestEventListenerInterface* UnitTestImpl::result_printer() {
+  if (result_printer_ != NULL) {
+    return result_printer_;
+  }
+
+#ifdef GTEST_HAS_DEATH_TEST
+  if (internal_run_death_test_flag_.get() != NULL) {
+    result_printer_ = new NullUnitTestResultPrinter;
+    return result_printer_;
+  }
+#endif  // GTEST_HAS_DEATH_TEST
+
+  UnitTestEventsRepeater *repeater = new UnitTestEventsRepeater;
+  const String& output_format = internal::UnitTestOptions::GetOutputFormat();
+  if (output_format == "xml") {
+    repeater->AddListener(new XmlUnitTestResultPrinter(
+        internal::UnitTestOptions::GetOutputFile().c_str()));
+  } else if (output_format != "") {
+      printf("WARNING: unrecognized output format \"%s\" ignored.\n",
+             output_format.c_str());
+      fflush(stdout);
+  }
+  repeater->AddListener(new PrettyUnitTestResultPrinter);
+  result_printer_ = repeater;
+  return result_printer_;
+}
+
+// Sets the OS stack trace getter.
+//
+// Does nothing if the input and the current OS stack trace getter are
+// the same; otherwise, deletes the old getter and makes the input the
+// current getter.
+void UnitTestImpl::set_os_stack_trace_getter(
+    OsStackTraceGetterInterface* getter) {
+  if (os_stack_trace_getter_ != getter) {
+    delete os_stack_trace_getter_;
+    os_stack_trace_getter_ = getter;
+  }
+}
+
+// Returns the current OS stack trace getter if it is not NULL;
+// otherwise, creates an OsStackTraceGetter, makes it the current
+// getter, and returns it.
+OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
+  if (os_stack_trace_getter_ == NULL) {
+    os_stack_trace_getter_ = new OsStackTraceGetter;
+  }
+
+  return os_stack_trace_getter_;
+}
+
+// Returns the TestResult for the test that's currently running, or
+// the TestResult for the ad hoc test if no test is running.
+internal::TestResult* UnitTestImpl::current_test_result() {
+  return current_test_info_ ?
+    current_test_info_->impl()->result() : &ad_hoc_test_result_;
+}
+
+// TestInfoImpl constructor.
+TestInfoImpl::TestInfoImpl(TestInfo* parent,
+                           const char* test_case_name,
+                           const char* name,
+                           TypeId fixture_class_id,
+                           TestMaker maker) :
+    parent_(parent),
+    test_case_name_(String(test_case_name)),
+    name_(String(name)),
+    fixture_class_id_(fixture_class_id),
+    should_run_(false),
+    is_disabled_(false),
+    maker_(maker) {
+}
+
+// TestInfoImpl destructor.
+TestInfoImpl::~TestInfoImpl() {
+}
+
+}  // namespace internal
+
+namespace internal {
+
+// Parses a string as a command line flag.  The string should have
+// the format "--flag=value".  When def_optional is true, the "=value"
+// part can be omitted.
+//
+// Returns the value of the flag, or NULL if the parsing failed.
+const char* ParseFlagValue(const char* str,
+                           const char* flag,
+                           bool def_optional) {
+  // str and flag must not be NULL.
+  if (str == NULL || flag == NULL) return NULL;
+
+  // The flag must start with "--" followed by GTEST_FLAG_PREFIX.
+  const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX, flag);
+  const size_t flag_len = flag_str.GetLength();
+  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
+
+  // Skips the flag name.
+  const char* flag_end = str + flag_len;
+
+  // When def_optional is true, it's OK to not have a "=value" part.
+  if (def_optional && (flag_end[0] == '\0')) {
+    return flag_end;
+  }
+
+  // If def_optional is true and there are more characters after the
+  // flag name, or if def_optional is false, there must be a '=' after
+  // the flag name.
+  if (flag_end[0] != '=') return NULL;
+
+  // Returns the string after "=".
+  return flag_end + 1;
+}
+
+// Parses a string for a bool flag, in the form of either
+// "--flag=value" or "--flag".
+//
+// In the former case, the value is taken as true as long as it does
+// not start with '0', 'f', or 'F'.
+//
+// In the latter case, the value is taken as true.
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseFlagValue(str, flag, true);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Converts the string value to a bool.
+  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
+  return true;
+}
+
+// Parses a string for an Int32 flag, in the form of
+// "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+bool ParseInt32Flag(const char* str, const char* flag, Int32* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseFlagValue(str, flag, false);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Sets *value to the value of the flag.
+  return ParseInt32(Message() << "The value of flag --" << flag,
+                    value_str, value);
+}
+
+// Parses a string for a string flag, in the form of
+// "--flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+bool ParseStringFlag(const char* str, const char* flag, String* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseFlagValue(str, flag, false);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Sets *value to the value of the flag.
+  *value = value_str;
+  return true;
+}
+
+// The internal implementation of ParseGTestFlags().
+//
+// The type parameter CharType can be instantiated to either char or
+// wchar_t.
+template <typename CharType>
+void ParseGTestFlagsImpl(int* argc, CharType** argv) {
+  g_parse_gtest_flags_called = true;
+  if (*argc <= 0) return;
+
+#ifdef GTEST_HAS_DEATH_TEST
+  g_argvs.clear();
+  for (int i = 0; i != *argc; i++) {
+    g_argvs.push_back(StreamableToString(argv[i]));
+  }
+#endif  // GTEST_HAS_DEATH_TEST
+
+  for (int i = 1; i != *argc; i++) {
+    const String arg_string = StreamableToString(argv[i]);
+    const char* const arg = arg_string.c_str();
+
+    using internal::ParseBoolFlag;
+    using internal::ParseInt32Flag;
+    using internal::ParseStringFlag;
+
+    // Do we see a Google Test flag?
+    if (ParseBoolFlag(arg, kBreakOnFailureFlag,
+                      &GTEST_FLAG(break_on_failure)) ||
+        ParseBoolFlag(arg, kCatchExceptionsFlag,
+                      &GTEST_FLAG(catch_exceptions)) ||
+        ParseStringFlag(arg, kColorFlag, &GTEST_FLAG(color)) ||
+        ParseStringFlag(arg, kDeathTestStyleFlag,
+                        &GTEST_FLAG(death_test_style)) ||
+        ParseStringFlag(arg, kFilterFlag, &GTEST_FLAG(filter)) ||
+        ParseStringFlag(arg, kInternalRunDeathTestFlag,
+                        &GTEST_FLAG(internal_run_death_test)) ||
+        ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||
+        ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||
+        ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat))
+        ) {
+      // Yes.  Shift the remainder of the argv list left by one.  Note
+      // that argv has (*argc + 1) elements, the last one always being
+      // NULL.  The following loop moves the trailing NULL element as
+      // well.
+      for (int j = i; j != *argc; j++) {
+        argv[j] = argv[j + 1];
+      }
+
+      // Decrements the argument count.
+      (*argc)--;
+
+      // We also need to decrement the iterator as we just removed
+      // an element.
+      i--;
+    }
+  }
+}
+
+}  // namespace internal
+
+// Parses a command line for the flags that Google Test recognizes.
+// Whenever a Google Test flag is seen, it is removed from argv, and *argc
+// is decremented.
+//
+// No value is returned.  Instead, the Google Test flag variables are
+// updated.
+void ParseGTestFlags(int* argc, char** argv) {
+  internal::g_executable_path = argv[0];
+  internal::ParseGTestFlagsImpl(argc, argv);
+}
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+#ifdef GTEST_OS_WINDOWS
+void ParseGTestFlags(int* argc, wchar_t** argv) {
+  // g_executable_path uses normal characters rather than wide chars, so call
+  // StreamableToString to convert argv[0] to normal characters (utf8 encoding).
+  internal::g_executable_path = internal::StreamableToString(argv[0]);
+  internal::ParseGTestFlagsImpl(argc, argv);
+}
+#endif  // GTEST_OS_WINDOWS
+
+}  // namespace testing
diff --git a/src/gtest/gtest.h b/src/gtest/gtest.h
new file mode 100644
index 0000000..4e3d7bc
--- /dev/null
+++ b/src/gtest/gtest.h
@@ -0,0 +1,1243 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines the public API for Google Test.  It should be
+// included by any test program that uses Google Test.
+//
+// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
+// leave some internal implementation details in this header file.
+// They are clearly marked by comments like this:
+//
+//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+//
+// Such code is NOT meant to be used by a user directly, and is subject
+// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user
+// program!
+//
+// Acknowledgment: Google Test borrowed the idea of automatic test
+// registration from Barthelemy Dagenais' (barthelemy@prologique.com)
+// easyUnit framework.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_H_
+
+#ifndef GTEST_NOT_MAC_FRAMEWORK_MODE
+// Protobuf never uses gTest in "mac framework mode".
+#define GTEST_NOT_MAC_FRAMEWORK_MODE
+#endif
+
+// The following platform macros are used throughout Google Test:
+//   _WIN32_WCE      Windows CE     (set in project files)
+//   __SYMBIAN32__   Symbian        (set by Symbian tool chain)
+//
+// Note that even though _MSC_VER and _WIN32_WCE really indicate a compiler
+// and a Win32 implementation, respectively, we use them to indicate the
+// combination of compiler - Win 32 API - C library, since the code currently
+// only supports:
+// Windows proper with Visual C++ and MS C library (_MSC_VER && !_WIN32_WCE) and
+// Windows Mobile with Visual C++ and no C library (_WIN32_WCE).
+
+#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+// When using Google Test on the Mac as a framework, all the includes
+// will be in the framework headers folder along with gtest.h.  Define
+// GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on the
+// Mac and are not using it as a framework.  More info on frameworks
+// available here:
+// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/
+// Concepts/WhatAreFrameworks.html.
+#include "gtest-death-test.h"  // NOLINT
+#include "gtest-internal.h"  // NOLINT
+#include "gtest-message.h"  // NOLINT
+#include "gtest-string.h"  // NOLINT
+#include "gtest_prod.h"  // NOLINT
+#else
+#include <gtest/internal/gtest-internal.h>
+#include <gtest/internal/gtest-string.h>
+#include <gtest/gtest-death-test.h>
+#include <gtest/gtest-message.h>
+#include <gtest/gtest_prod.h>
+#endif  // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+
+// Depending on the platform, different string classes are available.
+// On Windows, ::std::string compiles only when exceptions are
+// enabled.  On Linux, in addition to ::std::string, Google also makes
+// use of class ::string, which has the same interface as
+// ::std::string, but has a different implementation.
+//
+// The user can tell us whether ::std::string is available in his
+// environment by defining the macro GTEST_HAS_STD_STRING to either 1
+// or 0 on the compiler command line.  He can also define
+// GTEST_HAS_GLOBAL_STRING to 1 to indicate that ::string is available
+// AND is a distinct type to ::std::string, or define it to 0 to
+// indicate otherwise.
+//
+// If the user's ::std::string and ::string are the same class due to
+// aliasing, he should define GTEST_HAS_STD_STRING to 1 and
+// GTEST_HAS_GLOBAL_STRING to 0.
+//
+// If the user doesn't define GTEST_HAS_STD_STRING and/or
+// GTEST_HAS_GLOBAL_STRING, they are defined heuristically.
+
+namespace testing {
+
+// The upper limit for valid stack trace depths.
+const int kMaxStackTraceDepth = 100;
+
+// This flag specifies the maximum number of stack frames to be
+// printed in a failure message.
+GTEST_DECLARE_int32(stack_trace_depth);
+
+// This flag controls whether Google Test includes Google Test internal
+// stack frames in failure stack traces.
+GTEST_DECLARE_bool(show_internal_stack_frames);
+
+// The possible outcomes of a test part (i.e. an assertion or an
+// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
+enum TestPartResultType {
+  TPRT_SUCCESS,           // Succeeded.
+  TPRT_NONFATAL_FAILURE,  // Failed but the test can continue.
+  TPRT_FATAL_FAILURE      // Failed and the test should be terminated.
+};
+
+namespace internal {
+
+class GTestFlagSaver;
+
+// Converts a streamable value to a String.  A NULL pointer is
+// converted to "(null)".  When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+// Declared in gtest-internal.h but defined here, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable) {
+  return (Message() << streamable).GetString();
+}
+
+}  // namespace internal
+
+// A class for indicating whether an assertion was successful.  When
+// the assertion wasn't successful, the AssertionResult object
+// remembers a non-empty message that described how it failed.
+//
+// This class is useful for defining predicate-format functions to be
+// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
+//
+// The constructor of AssertionResult is private.  To create an
+// instance of this class, use one of the factory functions
+// (AssertionSuccess() and AssertionFailure()).
+//
+// For example, in order to be able to write:
+//
+//   // Verifies that Foo() returns an even number.
+//   EXPECT_PRED_FORMAT1(IsEven, Foo());
+//
+// you just need to define:
+//
+//   testing::AssertionResult IsEven(const char* expr, int n) {
+//     if ((n % 2) == 0) return testing::AssertionSuccess();
+//
+//     Message msg;
+//     msg << "Expected: " << expr << " is even\n"
+//         << "  Actual: it's " << n;
+//     return testing::AssertionFailure(msg);
+//   }
+//
+// If Foo() returns 5, you will see the following message:
+//
+//   Expected: Foo() is even
+//     Actual: it's 5
+class AssertionResult {
+ public:
+  // Declares factory functions for making successful and failed
+  // assertion results as friends.
+  friend AssertionResult AssertionSuccess();
+  friend AssertionResult AssertionFailure(const Message&);
+
+  // Returns true iff the assertion succeeded.
+  operator bool() const { return failure_message_.c_str() == NULL; }  // NOLINT
+
+  // Returns the assertion's failure message.
+  const char* failure_message() const { return failure_message_.c_str(); }
+
+ private:
+  // The default constructor.  It is used when the assertion succeeded.
+  AssertionResult() {}
+
+  // The constructor used when the assertion failed.
+  explicit AssertionResult(const internal::String& failure_message);
+
+  // Stores the assertion's failure message.
+  internal::String failure_message_;
+};
+
+// Makes a successful assertion result.
+AssertionResult AssertionSuccess();
+
+// Makes a failed assertion result with the given failure message.
+AssertionResult AssertionFailure(const Message& msg);
+
+// The abstract class that all tests inherit from.
+//
+// In Google Test, a unit test program contains one or many TestCases, and
+// each TestCase contains one or many Tests.
+//
+// When you define a test using the TEST macro, you don't need to
+// explicitly derive from Test - the TEST macro automatically does
+// this for you.
+//
+// The only time you derive from Test is when defining a test fixture
+// to be used a TEST_F.  For example:
+//
+//   class FooTest : public testing::Test {
+//    protected:
+//     virtual void SetUp() { ... }
+//     virtual void TearDown() { ... }
+//     ...
+//   };
+//
+//   TEST_F(FooTest, Bar) { ... }
+//   TEST_F(FooTest, Baz) { ... }
+//
+// Test is not copyable.
+class Test {
+ public:
+  friend class internal::TestInfoImpl;
+
+  // Defines types for pointers to functions that set up and tear down
+  // a test case.
+  typedef void (*SetUpTestCaseFunc)();
+  typedef void (*TearDownTestCaseFunc)();
+
+  // The d'tor is virtual as we intend to inherit from Test.
+  virtual ~Test();
+
+  // Returns true iff the current test has a fatal failure.
+  static bool HasFatalFailure();
+
+  // Logs a property for the current test.  Only the last value for a given
+  // key is remembered.
+  // These are public static so they can be called from utility functions
+  // that are not members of the test fixture.
+  // The arguments are const char* instead strings, as Google Test is used
+  // on platforms where string doesn't compile.
+  //
+  // Note that a driving consideration for these RecordProperty methods
+  // was to produce xml output suited to the Greenspan charting utility,
+  // which at present will only chart values that fit in a 32-bit int. It
+  // is the user's responsibility to restrict their values to 32-bit ints
+  // if they intend them to be used with Greenspan.
+  static void RecordProperty(const char* key, const char* value);
+  static void RecordProperty(const char* key, int value);
+
+ protected:
+  // Creates a Test object.
+  Test();
+
+  // Sets up the stuff shared by all tests in this test case.
+  //
+  // Google Test will call Foo::SetUpTestCase() before running the first
+  // test in test case Foo.  Hence a sub-class can define its own
+  // SetUpTestCase() method to shadow the one defined in the super
+  // class.
+  static void SetUpTestCase() {}
+
+  // Tears down the stuff shared by all tests in this test case.
+  //
+  // Google Test will call Foo::TearDownTestCase() after running the last
+  // test in test case Foo.  Hence a sub-class can define its own
+  // TearDownTestCase() method to shadow the one defined in the super
+  // class.
+  static void TearDownTestCase() {}
+
+  // Sets up the test fixture.
+  virtual void SetUp();
+
+  // Tears down the test fixture.
+  virtual void TearDown();
+
+ private:
+  // Returns true iff the current test has the same fixture class as
+  // the first test in the current test case.
+  static bool HasSameFixtureClass();
+
+  // Runs the test after the test fixture has been set up.
+  //
+  // A sub-class must implement this to define the test logic.
+  //
+  // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.
+  // Instead, use the TEST or TEST_F macro.
+  virtual void TestBody() = 0;
+
+  // Sets up, executes, and tears down the test.
+  void Run();
+
+  // Uses a GTestFlagSaver to save and restore all Google Test flags.
+  const internal::GTestFlagSaver* const gtest_flag_saver_;
+
+  // Often a user mis-spells SetUp() as Setup() and spends a long time
+  // wondering why it is never called by Google Test.  The declaration of
+  // the following method is solely for catching such an error at
+  // compile time:
+  //
+  //   - The return type is deliberately chosen to be not void, so it
+  //   will be a conflict if a user declares void Setup() in his test
+  //   fixture.
+  //
+  //   - This method is private, so it will be another compiler error
+  //   if a user calls it from his test fixture.
+  //
+  // DO NOT OVERRIDE THIS FUNCTION.
+  //
+  // If you see an error about overriding the following function or
+  // about it being private, you have mis-spelled SetUp() as Setup().
+  struct Setup_should_be_spelled_SetUp {};
+  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+
+  // We disallow copying Tests.
+  GTEST_DISALLOW_COPY_AND_ASSIGN(Test);
+};
+
+
+// Defines the type of a function pointer that creates a Test object
+// when invoked.
+typedef Test* (*TestMaker)();
+
+
+// A TestInfo object stores the following information about a test:
+//
+//   Test case name
+//   Test name
+//   Whether the test should be run
+//   A function pointer that creates the test object when invoked
+//   Test result
+//
+// The constructor of TestInfo registers itself with the UnitTest
+// singleton such that the RUN_ALL_TESTS() macro knows which tests to
+// run.
+class TestInfo {
+ public:
+  // Destructs a TestInfo object.  This function is not virtual, so
+  // don't inherit from TestInfo.
+  ~TestInfo();
+
+  // Creates a TestInfo object and registers it with the UnitTest
+  // singleton; returns the created object.
+  //
+  // Arguments:
+  //
+  //   test_case_name:   name of the test case
+  //   name:             name of the test
+  //   fixture_class_id: ID of the test fixture class
+  //   set_up_tc:        pointer to the function that sets up the test case
+  //   tear_down_tc:     pointer to the function that tears down the test case
+  //   maker:            pointer to the function that creates a test object
+  //
+  // This is public only because it's needed by the TEST and TEST_F macros.
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  static TestInfo* MakeAndRegisterInstance(
+      const char* test_case_name,
+      const char* name,
+      internal::TypeId fixture_class_id,
+      Test::SetUpTestCaseFunc set_up_tc,
+      Test::TearDownTestCaseFunc tear_down_tc,
+      TestMaker maker);
+
+  // Returns the test case name.
+  const char* test_case_name() const;
+
+  // Returns the test name.
+  const char* name() const;
+
+  // Returns true if this test should run.
+  //
+  // Google Test allows the user to filter the tests by their full names.
+  // The full name of a test Bar in test case Foo is defined as
+  // "Foo.Bar".  Only the tests that match the filter will run.
+  //
+  // A filter is a colon-separated list of glob (not regex) patterns,
+  // optionally followed by a '-' and a colon-separated list of
+  // negative patterns (tests to exclude).  A test is run if it
+  // matches one of the positive patterns and does not match any of
+  // the negative patterns.
+  //
+  // For example, *A*:Foo.* is a filter that matches any string that
+  // contains the character 'A' or starts with "Foo.".
+  bool should_run() const;
+
+  // Returns the result of the test.
+  const internal::TestResult* result() const;
+ private:
+#ifdef GTEST_HAS_DEATH_TEST
+  friend class internal::DefaultDeathTestFactory;
+#endif
+  friend class internal::TestInfoImpl;
+  friend class internal::UnitTestImpl;
+  friend class Test;
+  friend class TestCase;
+
+  // Increments the number of death tests encountered in this test so
+  // far.
+  int increment_death_test_count();
+
+  // Accessors for the implementation object.
+  internal::TestInfoImpl* impl() { return impl_; }
+  const internal::TestInfoImpl* impl() const { return impl_; }
+
+  // Constructs a TestInfo object.
+  TestInfo(const char* test_case_name, const char* name,
+           internal::TypeId fixture_class_id, TestMaker maker);
+
+  // An opaque implementation object.
+  internal::TestInfoImpl* impl_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(TestInfo);
+};
+
+// An Environment object is capable of setting up and tearing down an
+// environment.  The user should subclass this to define his own
+// environment(s).
+//
+// An Environment object does the set-up and tear-down in virtual
+// methods SetUp() and TearDown() instead of the constructor and the
+// destructor, as:
+//
+//   1. You cannot safely throw from a destructor.  This is a problem
+//      as in some cases Google Test is used where exceptions are enabled, and
+//      we may want to implement ASSERT_* using exceptions where they are
+//      available.
+//   2. You cannot use ASSERT_* directly in a constructor or
+//      destructor.
+class Environment {
+ public:
+  // The d'tor is virtual as we need to subclass Environment.
+  virtual ~Environment() {}
+
+  // Override this to define how to set up the environment.
+  virtual void SetUp() {}
+
+  // Override this to define how to tear down the environment.
+  virtual void TearDown() {}
+ private:
+  // If you see an error about overriding the following function or
+  // about it being private, you have mis-spelled SetUp() as Setup().
+  struct Setup_should_be_spelled_SetUp {};
+  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+};
+
+// A UnitTest consists of a list of TestCases.
+//
+// This is a singleton class.  The only instance of UnitTest is
+// created when UnitTest::GetInstance() is first called.  This
+// instance is never deleted.
+//
+// UnitTest is not copyable.
+//
+// This class is thread-safe as long as the methods are called
+// according to their specification.
+class UnitTest {
+ public:
+  // Gets the singleton UnitTest object.  The first time this method
+  // is called, a UnitTest object is constructed and returned.
+  // Consecutive calls will return the same object.
+  static UnitTest* GetInstance();
+
+  // Registers and returns a global test environment.  When a test
+  // program is run, all global test environments will be set-up in
+  // the order they were registered.  After all tests in the program
+  // have finished, all global test environments will be torn-down in
+  // the *reverse* order they were registered.
+  //
+  // The UnitTest object takes ownership of the given environment.
+  //
+  // This method can only be called from the main thread.
+  Environment* AddEnvironment(Environment* env);
+
+  // Adds a TestPartResult to the current TestResult object.  All
+  // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)
+  // eventually call this to report their results.  The user code
+  // should use the assertion macros instead of calling this directly.
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  void AddTestPartResult(TestPartResultType result_type,
+                         const char* file_name,
+                         int line_number,
+                         const internal::String& message,
+                         const internal::String& os_stack_trace);
+
+  // Adds a TestProperty to the current TestResult object. If the result already
+  // contains a property with the same key, the value will be updated.
+  void RecordPropertyForCurrentTest(const char* key, const char* value);
+
+  // Runs all tests in this UnitTest object and prints the result.
+  // Returns 0 if successful, or 1 otherwise.
+  //
+  // This method can only be called from the main thread.
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  int Run() GTEST_MUST_USE_RESULT;
+
+  // Returns the TestCase object for the test that's currently running,
+  // or NULL if no test is running.
+  const TestCase* current_test_case() const;
+
+  // Returns the TestInfo object for the test that's currently running,
+  // or NULL if no test is running.
+  const TestInfo* current_test_info() const;
+
+  // Accessors for the implementation object.
+  internal::UnitTestImpl* impl() { return impl_; }
+  const internal::UnitTestImpl* impl() const { return impl_; }
+ private:
+  // ScopedTrace is a friend as it needs to modify the per-thread
+  // trace stack, which is a private member of UnitTest.
+  friend class internal::ScopedTrace;
+
+  // Creates an empty UnitTest.
+  UnitTest();
+
+  // D'tor
+  virtual ~UnitTest();
+
+  // Pushes a trace defined by SCOPED_TRACE() on to the per-thread
+  // Google Test trace stack.
+  void PushGTestTrace(const internal::TraceInfo& trace);
+
+  // Pops a trace from the per-thread Google Test trace stack.
+  void PopGTestTrace();
+
+  // Protects mutable state in *impl_.  This is mutable as some const
+  // methods need to lock it too.
+  mutable internal::Mutex mutex_;
+
+  // Opaque implementation object.  This field is never changed once
+  // the object is constructed.  We don't mark it as const here, as
+  // doing so will cause a warning in the constructor of UnitTest.
+  // Mutable state in *impl_ is protected by mutex_.
+  internal::UnitTestImpl* impl_;
+
+  // We disallow copying UnitTest.
+  GTEST_DISALLOW_COPY_AND_ASSIGN(UnitTest);
+};
+
+// A convenient wrapper for adding an environment for the test
+// program.
+//
+// You should call this before RUN_ALL_TESTS() is called, probably in
+// main().  If you use gtest_main, you need to call this before main()
+// starts for it to take effect.  For example, you can define a global
+// variable like this:
+//
+//   testing::Environment* const foo_env =
+//       testing::AddGlobalTestEnvironment(new FooEnvironment);
+//
+// However, we strongly recommend you to write your own main() and
+// call AddGlobalTestEnvironment() there, as relying on initialization
+// of global variables makes the code harder to read and may cause
+// problems when you register multiple environments from different
+// translation units and the environments have dependencies among them
+// (remember that the compiler doesn't guarantee the order in which
+// global variables from different translation units are initialized).
+inline Environment* AddGlobalTestEnvironment(Environment* env) {
+  return UnitTest::GetInstance()->AddEnvironment(env);
+}
+
+// Parses a command line for the flags that Google Test recognizes.
+// Whenever a Google Test flag is seen, it is removed from argv, and *argc
+// is decremented.
+//
+// No value is returned.  Instead, the Google Test flag variables are
+// updated.
+void ParseGTestFlags(int* argc, char** argv);
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+#ifdef GTEST_OS_WINDOWS
+void ParseGTestFlags(int* argc, wchar_t** argv);
+#endif  // GTEST_OS_WINDOWS
+
+namespace internal {
+
+// These overloaded versions handle ::std::string and ::std::wstring.
+#if GTEST_HAS_STD_STRING
+inline String FormatForFailureMessage(const ::std::string& str) {
+  return (Message() << '"' << str << '"').GetString();
+}
+#endif  // GTEST_HAS_STD_STRING
+#if GTEST_HAS_STD_WSTRING
+inline String FormatForFailureMessage(const ::std::wstring& wstr) {
+  return (Message() << "L\"" << wstr << '"').GetString();
+}
+#endif  // GTEST_HAS_STD_WSTRING
+
+// These overloaded versions handle ::string and ::wstring.
+#if GTEST_HAS_GLOBAL_STRING
+inline String FormatForFailureMessage(const ::string& str) {
+  return (Message() << '"' << str << '"').GetString();
+}
+#endif  // GTEST_HAS_GLOBAL_STRING
+#if GTEST_HAS_GLOBAL_WSTRING
+inline String FormatForFailureMessage(const ::wstring& wstr) {
+  return (Message() << "L\"" << wstr << '"').GetString();
+}
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
+// operand to be used in a failure message.  The type (but not value)
+// of the other operand may affect the format.  This allows us to
+// print a char* as a raw pointer when it is compared against another
+// char*, and print it as a C string when it is compared against an
+// std::string object, for example.
+//
+// The default implementation ignores the type of the other operand.
+// Some specialized versions are used to handle formatting wide or
+// narrow C strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+template <typename T1, typename T2>
+String FormatForComparisonFailureMessage(const T1& value,
+                                         const T2& /* other_operand */) {
+  return FormatForFailureMessage(value);
+}
+
+// The helper function for {ASSERT|EXPECT}_EQ.
+template <typename T1, typename T2>
+AssertionResult CmpHelperEQ(const char* expected_expression,
+                            const char* actual_expression,
+                            const T1& expected,
+                            const T2& actual) {
+  if (expected == actual) {
+    return AssertionSuccess();
+  }
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   FormatForComparisonFailureMessage(expected, actual),
+                   FormatForComparisonFailureMessage(actual, expected),
+                   false);
+}
+
+// With this overloaded version, we allow anonymous enums to be used
+// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums
+// can be implicitly cast to BiggestInt.
+AssertionResult CmpHelperEQ(const char* expected_expression,
+                            const char* actual_expression,
+                            BiggestInt expected,
+                            BiggestInt actual);
+
+// The helper class for {ASSERT|EXPECT}_EQ.  The template argument
+// lhs_is_null_literal is true iff the first argument to ASSERT_EQ()
+// is a null pointer literal.  The following default implementation is
+// for lhs_is_null_literal being false.
+template <bool lhs_is_null_literal>
+class EqHelper {
+ public:
+  // This templatized version is for the general case.
+  template <typename T1, typename T2>
+  static AssertionResult Compare(const char* expected_expression,
+                                 const char* actual_expression,
+                                 const T1& expected,
+                                 const T2& actual) {
+    return CmpHelperEQ(expected_expression, actual_expression, expected,
+                       actual);
+  }
+
+  // With this overloaded version, we allow anonymous enums to be used
+  // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous
+  // enums can be implicitly cast to BiggestInt.
+  //
+  // Even though its body looks the same as the above version, we
+  // cannot merge the two, as it will make anonymous enums unhappy.
+  static AssertionResult Compare(const char* expected_expression,
+                                 const char* actual_expression,
+                                 BiggestInt expected,
+                                 BiggestInt actual) {
+    return CmpHelperEQ(expected_expression, actual_expression, expected,
+                       actual);
+  }
+};
+
+// This specialization is used when the first argument to ASSERT_EQ()
+// is a null pointer literal.
+template <>
+class EqHelper<true> {
+ public:
+  // We define two overloaded versions of Compare().  The first
+  // version will be picked when the second argument to ASSERT_EQ() is
+  // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or
+  // EXPECT_EQ(false, a_bool).
+  template <typename T1, typename T2>
+  static AssertionResult Compare(const char* expected_expression,
+                                 const char* actual_expression,
+                                 const T1& expected,
+                                 const T2& actual) {
+    return CmpHelperEQ(expected_expression, actual_expression, expected,
+                       actual);
+  }
+
+  // This version will be picked when the second argument to
+  // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer).
+  template <typename T1, typename T2>
+  static AssertionResult Compare(const char* expected_expression,
+                                 const char* actual_expression,
+                                 const T1& expected,
+                                 T2* actual) {
+    // We already know that 'expected' is a null pointer.
+    return CmpHelperEQ(expected_expression, actual_expression,
+                       static_cast<T2*>(NULL), actual);
+  }
+};
+
+// A macro for implementing the helper functions needed to implement
+// ASSERT_?? and EXPECT_??.  It is here just to avoid copy-and-paste
+// of similar code.
+//
+// For each templatized helper function, we also define an overloaded
+// version for BiggestInt in order to reduce code bloat and allow
+// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled
+// with gcc 4.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+#define GTEST_IMPL_CMP_HELPER(op_name, op)\
+template <typename T1, typename T2>\
+AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
+                                   const T1& val1, const T2& val2) {\
+  if (val1 op val2) {\
+    return AssertionSuccess();\
+  } else {\
+    Message msg;\
+    msg << "Expected: (" << expr1 << ") " #op " (" << expr2\
+        << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\
+        << " vs " << FormatForComparisonFailureMessage(val2, val1);\
+    return AssertionFailure(msg);\
+  }\
+}\
+AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
+                                   BiggestInt val1, BiggestInt val2);
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+
+// Implements the helper function for {ASSERT|EXPECT}_NE
+GTEST_IMPL_CMP_HELPER(NE, !=)
+// Implements the helper function for {ASSERT|EXPECT}_LE
+GTEST_IMPL_CMP_HELPER(LE, <=)
+// Implements the helper function for {ASSERT|EXPECT}_LT
+GTEST_IMPL_CMP_HELPER(LT, < )
+// Implements the helper function for {ASSERT|EXPECT}_GE
+GTEST_IMPL_CMP_HELPER(GE, >=)
+// Implements the helper function for {ASSERT|EXPECT}_GT
+GTEST_IMPL_CMP_HELPER(GT, > )
+
+#undef GTEST_IMPL_CMP_HELPER
+
+// The helper function for {ASSERT|EXPECT}_STREQ.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                               const char* actual_expression,
+                               const char* expected,
+                               const char* actual);
+
+// The helper function for {ASSERT|EXPECT}_STRCASEEQ.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,
+                                   const char* actual_expression,
+                                   const char* expected,
+                                   const char* actual);
+
+// The helper function for {ASSERT|EXPECT}_STRNE.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                               const char* s2_expression,
+                               const char* s1,
+                               const char* s2);
+
+// The helper function for {ASSERT|EXPECT}_STRCASENE.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
+                                   const char* s2_expression,
+                                   const char* s1,
+                                   const char* s2);
+
+
+// Helper function for *_STREQ on wide strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+AssertionResult CmpHelperSTREQ(const char* expected_expression,
+                               const char* actual_expression,
+                               const wchar_t* expected,
+                               const wchar_t* actual);
+
+// Helper function for *_STRNE on wide strings.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+AssertionResult CmpHelperSTRNE(const char* s1_expression,
+                               const char* s2_expression,
+                               const wchar_t* s1,
+                               const wchar_t* s2);
+
+}  // namespace internal
+
+// IsSubstring() and IsNotSubstring() are intended to be used as the
+// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by
+// themselves.  They check whether needle is a substring of haystack
+// (NULL is considered a substring of itself only), and return an
+// appropriate error message when they fail.
+//
+// The {needle,haystack}_expr arguments are the stringified
+// expressions that generated the two real arguments.
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack);
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack);
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack);
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack);
+#if GTEST_HAS_STD_STRING
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack);
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack);
+#endif  // GTEST_HAS_STD_STRING
+#if GTEST_HAS_STD_WSTRING
+AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack);
+AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack);
+#endif  // GTEST_HAS_STD_WSTRING
+
+namespace internal {
+
+// Helper template function for comparing floating-points.
+//
+// Template parameter:
+//
+//   RawType: the raw floating-point type (either float or double)
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+template <typename RawType>
+AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression,
+                                         const char* actual_expression,
+                                         RawType expected,
+                                         RawType actual) {
+  const FloatingPoint<RawType> lhs(expected), rhs(actual);
+
+  if (lhs.AlmostEquals(rhs)) {
+    return AssertionSuccess();
+  }
+
+  StrStream expected_ss;
+  expected_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+              << expected;
+
+  StrStream actual_ss;
+  actual_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)
+            << actual;
+
+  return EqFailure(expected_expression,
+                   actual_expression,
+                   StrStreamToString(&expected_ss),
+                   StrStreamToString(&actual_ss),
+                   false);
+}
+
+// Helper function for implementing ASSERT_NEAR.
+//
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+AssertionResult DoubleNearPredFormat(const char* expr1,
+                                     const char* expr2,
+                                     const char* abs_error_expr,
+                                     double val1,
+                                     double val2,
+                                     double abs_error);
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+// A class that enables one to stream messages to assertion macros
+class AssertHelper {
+ public:
+  // Constructor.
+  AssertHelper(TestPartResultType type, const char* file, int line,
+               const char* message);
+  // Message assignment is a semantic trick to enable assertion
+  // streaming; see the GTEST_MESSAGE macro below.
+  void operator=(const Message& message) const;
+ private:
+  TestPartResultType const type_;
+  const char*        const file_;
+  int                const line_;
+  String             const message_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(AssertHelper);
+};
+
+}  // namespace internal
+
+// Macros for indicating success/failure in test code.
+
+// ADD_FAILURE unconditionally adds a failure to the current test.
+// SUCCEED generates a success - it doesn't automatically make the
+// current test successful, as a test is only successful when it has
+// no failure.
+//
+// EXPECT_* verifies that a certain condition is satisfied.  If not,
+// it behaves like ADD_FAILURE.  In particular:
+//
+//   EXPECT_TRUE  verifies that a Boolean condition is true.
+//   EXPECT_FALSE verifies that a Boolean condition is false.
+//
+// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except
+// that they will also abort the current function on failure.  People
+// usually want the fail-fast behavior of FAIL and ASSERT_*, but those
+// writing data-driven tests often find themselves using ADD_FAILURE
+// and EXPECT_* more.
+//
+// Examples:
+//
+//   EXPECT_TRUE(server.StatusIsOK());
+//   ASSERT_FALSE(server.HasPendingRequest(port))
+//       << "There are still pending requests " << "on port " << port;
+
+// Generates a nonfatal failure with a generic message.
+#define ADD_FAILURE() GTEST_NONFATAL_FAILURE("Failed")
+
+// Generates a fatal failure with a generic message.
+#define FAIL() GTEST_FATAL_FAILURE("Failed")
+
+// Generates a success with a generic message.
+#define SUCCEED() GTEST_SUCCESS("Succeeded")
+
+// Boolean assertions.
+#define EXPECT_TRUE(condition) \
+  GTEST_TEST_BOOLEAN(condition, #condition, false, true, \
+                     GTEST_NONFATAL_FAILURE)
+#define EXPECT_FALSE(condition) \
+  GTEST_TEST_BOOLEAN(!(condition), #condition, true, false, \
+                     GTEST_NONFATAL_FAILURE)
+#define ASSERT_TRUE(condition) \
+  GTEST_TEST_BOOLEAN(condition, #condition, false, true, \
+                     GTEST_FATAL_FAILURE)
+#define ASSERT_FALSE(condition) \
+  GTEST_TEST_BOOLEAN(!(condition), #condition, true, false, \
+                     GTEST_FATAL_FAILURE)
+
+// Includes the auto-generated header that implements a family of
+// generic predicate assertion macros.
+#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+// When using Google Test on the Mac as a framework, all the includes will be
+// in the framework headers folder along with gtest.h.
+// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on
+// the Mac and are not using it as a framework.
+// More info on frameworks available here:
+// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/
+// Concepts/WhatAreFrameworks.html.
+#include "gtest_pred_impl.h"  // NOLINT
+#else
+#include <gtest/gtest_pred_impl.h>
+#endif  // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+
+// Macros for testing equalities and inequalities.
+//
+//    * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
+//    * {ASSERT|EXPECT}_NE(v1, v2):           Tests that v1 != v2
+//    * {ASSERT|EXPECT}_LT(v1, v2):           Tests that v1 < v2
+//    * {ASSERT|EXPECT}_LE(v1, v2):           Tests that v1 <= v2
+//    * {ASSERT|EXPECT}_GT(v1, v2):           Tests that v1 > v2
+//    * {ASSERT|EXPECT}_GE(v1, v2):           Tests that v1 >= v2
+//
+// When they are not, Google Test prints both the tested expressions and
+// their actual values.  The values must be compatible built-in types,
+// or you will get a compiler error.  By "compatible" we mean that the
+// values can be compared by the respective operator.
+//
+// Note:
+//
+//   1. It is possible to make a user-defined type work with
+//   {ASSERT|EXPECT}_??(), but that requires overloading the
+//   comparison operators and is thus discouraged by the Google C++
+//   Usage Guide.  Therefore, you are advised to use the
+//   {ASSERT|EXPECT}_TRUE() macro to assert that two objects are
+//   equal.
+//
+//   2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on
+//   pointers (in particular, C strings).  Therefore, if you use it
+//   with two C strings, you are testing how their locations in memory
+//   are related, not how their content is related.  To compare two C
+//   strings by content, use {ASSERT|EXPECT}_STR*().
+//
+//   3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to
+//   {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you
+//   what the actual value is when it fails, and similarly for the
+//   other comparisons.
+//
+//   4. Do not depend on the order in which {ASSERT|EXPECT}_??()
+//   evaluate their arguments, which is undefined.
+//
+//   5. These macros evaluate their arguments exactly once.
+//
+// Examples:
+//
+//   EXPECT_NE(5, Foo());
+//   EXPECT_EQ(NULL, a_pointer);
+//   ASSERT_LT(i, array_size);
+//   ASSERT_GT(records.size(), 0) << "There is no record left.";
+
+#define EXPECT_EQ(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal:: \
+                      EqHelper<GTEST_IS_NULL_LITERAL(expected)>::Compare, \
+                      expected, actual)
+#define EXPECT_NE(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual)
+#define EXPECT_LE(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
+#define EXPECT_LT(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
+#define EXPECT_GE(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
+#define EXPECT_GT(val1, val2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
+
+#define ASSERT_EQ(expected, actual) \
+  ASSERT_PRED_FORMAT2(::testing::internal:: \
+                      EqHelper<GTEST_IS_NULL_LITERAL(expected)>::Compare, \
+                      expected, actual)
+#define ASSERT_NE(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
+#define ASSERT_LE(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
+#define ASSERT_LT(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
+#define ASSERT_GE(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
+#define ASSERT_GT(val1, val2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
+
+// C String Comparisons.  All tests treat NULL and any non-NULL string
+// as different.  Two NULLs are equal.
+//
+//    * {ASSERT|EXPECT}_STREQ(s1, s2):     Tests that s1 == s2
+//    * {ASSERT|EXPECT}_STRNE(s1, s2):     Tests that s1 != s2
+//    * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case
+//    * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case
+//
+// For wide or narrow string objects, you can use the
+// {ASSERT|EXPECT}_??() macros.
+//
+// Don't depend on the order in which the arguments are evaluated,
+// which is undefined.
+//
+// These macros evaluate their arguments exactly once.
+
+#define EXPECT_STREQ(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)
+#define EXPECT_STRNE(s1, s2) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
+#define EXPECT_STRCASEEQ(expected, actual) \
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)
+#define EXPECT_STRCASENE(s1, s2)\
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
+
+#define ASSERT_STREQ(expected, actual) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)
+#define ASSERT_STRNE(s1, s2) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
+#define ASSERT_STRCASEEQ(expected, actual) \
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)
+#define ASSERT_STRCASENE(s1, s2)\
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)
+
+// Macros for comparing floating-point numbers.
+//
+//    * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual):
+//         Tests that two float values are almost equal.
+//    * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual):
+//         Tests that two double values are almost equal.
+//    * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error):
+//         Tests that v1 and v2 are within the given distance to each other.
+//
+// Google Test uses ULP-based comparison to automatically pick a default
+// error bound that is appropriate for the operands.  See the
+// FloatingPoint template class in gtest-internal.h if you are
+// interested in the implementation details.
+
+#define EXPECT_FLOAT_EQ(expected, actual)\
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
+                      expected, actual)
+
+#define EXPECT_DOUBLE_EQ(expected, actual)\
+  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
+                      expected, actual)
+
+#define ASSERT_FLOAT_EQ(expected, actual)\
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
+                      expected, actual)
+
+#define ASSERT_DOUBLE_EQ(expected, actual)\
+  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
+                      expected, actual)
+
+#define EXPECT_NEAR(val1, val2, abs_error)\
+  EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
+                      val1, val2, abs_error)
+
+#define ASSERT_NEAR(val1, val2, abs_error)\
+  ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
+                      val1, val2, abs_error)
+
+// These predicate format functions work on floating-point values, and
+// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.
+//
+//   EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0);
+
+// Asserts that val1 is less than, or almost equal to, val2.  Fails
+// otherwise.  In particular, it fails if either val1 or val2 is NaN.
+AssertionResult FloatLE(const char* expr1, const char* expr2,
+                        float val1, float val2);
+AssertionResult DoubleLE(const char* expr1, const char* expr2,
+                         double val1, double val2);
+
+
+#ifdef GTEST_OS_WINDOWS
+
+// Macros that test for HRESULT failure and success, these are only useful
+// on Windows, and rely on Windows SDK macros and APIs to compile.
+//
+//    * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr)
+//
+// When expr unexpectedly fails or succeeds, Google Test prints the expected result
+// and the actual result with both a human-readable string representation of
+// the error, if available, as well as the hex result code.
+#define EXPECT_HRESULT_SUCCEEDED(expr) \
+    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
+
+#define ASSERT_HRESULT_SUCCEEDED(expr) \
+    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
+
+#define EXPECT_HRESULT_FAILED(expr) \
+    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
+
+#define ASSERT_HRESULT_FAILED(expr) \
+    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))
+
+#endif  // GTEST_OS_WINDOWS
+
+
+// Causes a trace (including the source file path, the current line
+// number, and the given message) to be included in every test failure
+// message generated by code in the current scope.  The effect is
+// undone when the control leaves the current scope.
+//
+// The message argument can be anything streamable to std::ostream.
+//
+// In the implementation, we include the current line number as part
+// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s
+// to appear in the same block - as long as they are on different
+// lines.
+#define SCOPED_TRACE(message) \
+  ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN(gtest_trace_, __LINE__)(\
+    __FILE__, __LINE__, ::testing::Message() << (message))
+
+
+// Defines a test.
+//
+// The first parameter is the name of the test case, and the second
+// parameter is the name of the test within the test case.
+//
+// The convention is to end the test case name with "Test".  For
+// example, a test case for the Foo class can be named FooTest.
+//
+// The user should put his test code between braces after using this
+// macro.  Example:
+//
+//   TEST(FooTest, InitializesCorrectly) {
+//     Foo foo;
+//     EXPECT_TRUE(foo.StatusIsOK());
+//   }
+
+#define TEST(test_case_name, test_name)\
+  GTEST_TEST(test_case_name, test_name, ::testing::Test)
+
+
+// Defines a test that uses a test fixture.
+//
+// The first parameter is the name of the test fixture class, which
+// also doubles as the test case name.  The second parameter is the
+// name of the test within the test case.
+//
+// A test fixture class must be declared earlier.  The user should put
+// his test code between braces after using this macro.  Example:
+//
+//   class FooTest : public testing::Test {
+//    protected:
+//     virtual void SetUp() { b_.AddElement(3); }
+//
+//     Foo a_;
+//     Foo b_;
+//   };
+//
+//   TEST_F(FooTest, InitializesCorrectly) {
+//     EXPECT_TRUE(a_.StatusIsOK());
+//   }
+//
+//   TEST_F(FooTest, ReturnsElementCountCorrectly) {
+//     EXPECT_EQ(0, a_.size());
+//     EXPECT_EQ(1, b_.size());
+//   }
+
+#define TEST_F(test_fixture, test_name)\
+  GTEST_TEST(test_fixture, test_name, test_fixture)
+
+// Use this macro in main() to run all tests.  It returns 0 if all
+// tests are successful, or 1 otherwise.
+//
+// RUN_ALL_TESTS() should be invoked after the command line has been
+// parsed by ParseGTestFlags().
+
+#define RUN_ALL_TESTS()\
+  (::testing::UnitTest::GetInstance()->Run())
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_H_
diff --git a/src/gtest/gtest_main.cc b/src/gtest/gtest_main.cc
new file mode 100644
index 0000000..c216bd2
--- /dev/null
+++ b/src/gtest/gtest_main.cc
@@ -0,0 +1,39 @@
+// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <iostream>
+
+#include <gtest/gtest.h>
+
+int main(int argc, char **argv) {
+  std::cout << "Running main() from gtest_main.cc\n";
+
+  testing::ParseGTestFlags(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/src/gtest/gtest_pred_impl.h b/src/gtest/gtest_pred_impl.h
new file mode 100644
index 0000000..984f793
--- /dev/null
+++ b/src/gtest/gtest_pred_impl.h
@@ -0,0 +1,368 @@
+// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is AUTOMATICALLY GENERATED on 06/22/2008 by command
+// 'gen_gtest_pred_impl.py 5'.  DO NOT EDIT BY HAND!
+//
+// Implements a family of generic predicate assertion macros.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
+
+// Makes sure this header is not included before gtest.h.
+#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
+#error Do not include gtest_pred_impl.h directly.  Include gtest.h instead.
+#endif  // GTEST_INCLUDE_GTEST_GTEST_H_
+
+// This header implements a family of generic predicate assertion
+// macros:
+//
+//   ASSERT_PRED_FORMAT1(pred_format, v1)
+//   ASSERT_PRED_FORMAT2(pred_format, v1, v2)
+//   ...
+//
+// where pred_format is a function or functor that takes n (in the
+// case of ASSERT_PRED_FORMATn) values and their source expression
+// text, and returns a testing::AssertionResult.  See the definition
+// of ASSERT_EQ in gtest.h for an example.
+//
+// If you don't care about formatting, you can use the more
+// restrictive version:
+//
+//   ASSERT_PRED1(pred, v1)
+//   ASSERT_PRED2(pred, v1, v2)
+//   ...
+//
+// where pred is an n-ary function or functor that returns bool,
+// and the values v1, v2, ..., must support the << operator for
+// streaming to std::ostream.
+//
+// We also define the EXPECT_* variations.
+//
+// For now we only support predicates whose arity is at most 5.
+// Please email googletestframework@googlegroups.com if you need
+// support for higher arities.
+
+// GTEST_ASSERT is the basic statement to which all of the assertions
+// in this file reduce.  Don't use this in your code.
+
+#define GTEST_ASSERT(expression, on_failure) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER \
+  if (const ::testing::AssertionResult gtest_ar = (expression)) \
+    ; \
+  else \
+    on_failure(gtest_ar.failure_message())
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED1.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1>
+AssertionResult AssertPred1Helper(const char* pred_text,
+                                  const char* e1,
+                                  Pred pred,
+                                  const T1& v1) {
+  if (pred(v1)) return AssertionSuccess();
+
+  Message msg;
+  msg << pred_text << "("
+      << e1 << ") evaluates to false, where"
+      << "\n" << e1 << " evaluates to " << v1;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT1(pred_format, v1, on_failure)\
+  GTEST_ASSERT(pred_format(#v1, v1),\
+               on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED1.  Don't use
+// this in your code.
+#define GTEST_PRED1(pred, v1, on_failure)\
+  GTEST_ASSERT(::testing::AssertPred1Helper(#pred, \
+                                 #v1, \
+                                 pred, \
+                                 v1), on_failure)
+
+// Unary predicate assertion macros.
+#define EXPECT_PRED_FORMAT1(pred_format, v1) \
+  GTEST_PRED_FORMAT1(pred_format, v1, GTEST_NONFATAL_FAILURE)
+#define EXPECT_PRED1(pred, v1) \
+  GTEST_PRED1(pred, v1, GTEST_NONFATAL_FAILURE)
+#define ASSERT_PRED_FORMAT1(pred_format, v1) \
+  GTEST_PRED_FORMAT1(pred_format, v1, GTEST_FATAL_FAILURE)
+#define ASSERT_PRED1(pred, v1) \
+  GTEST_PRED1(pred, v1, GTEST_FATAL_FAILURE)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED2.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2>
+AssertionResult AssertPred2Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2) {
+  if (pred(v1, v2)) return AssertionSuccess();
+
+  Message msg;
+  msg << pred_text << "("
+      << e1 << ", "
+      << e2 << ") evaluates to false, where"
+      << "\n" << e1 << " evaluates to " << v1
+      << "\n" << e2 << " evaluates to " << v2;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT2(pred_format, v1, v2, on_failure)\
+  GTEST_ASSERT(pred_format(#v1, #v2, v1, v2),\
+               on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED2.  Don't use
+// this in your code.
+#define GTEST_PRED2(pred, v1, v2, on_failure)\
+  GTEST_ASSERT(::testing::AssertPred2Helper(#pred, \
+                                 #v1, \
+                                 #v2, \
+                                 pred, \
+                                 v1, \
+                                 v2), on_failure)
+
+// Binary predicate assertion macros.
+#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
+  GTEST_PRED_FORMAT2(pred_format, v1, v2, GTEST_NONFATAL_FAILURE)
+#define EXPECT_PRED2(pred, v1, v2) \
+  GTEST_PRED2(pred, v1, v2, GTEST_NONFATAL_FAILURE)
+#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
+  GTEST_PRED_FORMAT2(pred_format, v1, v2, GTEST_FATAL_FAILURE)
+#define ASSERT_PRED2(pred, v1, v2) \
+  GTEST_PRED2(pred, v1, v2, GTEST_FATAL_FAILURE)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED3.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3>
+AssertionResult AssertPred3Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3) {
+  if (pred(v1, v2, v3)) return AssertionSuccess();
+
+  Message msg;
+  msg << pred_text << "("
+      << e1 << ", "
+      << e2 << ", "
+      << e3 << ") evaluates to false, where"
+      << "\n" << e1 << " evaluates to " << v1
+      << "\n" << e2 << " evaluates to " << v2
+      << "\n" << e3 << " evaluates to " << v3;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT3(pred_format, v1, v2, v3, on_failure)\
+  GTEST_ASSERT(pred_format(#v1, #v2, #v3, v1, v2, v3),\
+               on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED3.  Don't use
+// this in your code.
+#define GTEST_PRED3(pred, v1, v2, v3, on_failure)\
+  GTEST_ASSERT(::testing::AssertPred3Helper(#pred, \
+                                 #v1, \
+                                 #v2, \
+                                 #v3, \
+                                 pred, \
+                                 v1, \
+                                 v2, \
+                                 v3), on_failure)
+
+// Ternary predicate assertion macros.
+#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
+  GTEST_PRED_FORMAT3(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE)
+#define EXPECT_PRED3(pred, v1, v2, v3) \
+  GTEST_PRED3(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE)
+#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
+  GTEST_PRED_FORMAT3(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE)
+#define ASSERT_PRED3(pred, v1, v2, v3) \
+  GTEST_PRED3(pred, v1, v2, v3, GTEST_FATAL_FAILURE)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED4.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3,
+          typename T4>
+AssertionResult AssertPred4Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  const char* e4,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3,
+                                  const T4& v4) {
+  if (pred(v1, v2, v3, v4)) return AssertionSuccess();
+
+  Message msg;
+  msg << pred_text << "("
+      << e1 << ", "
+      << e2 << ", "
+      << e3 << ", "
+      << e4 << ") evaluates to false, where"
+      << "\n" << e1 << " evaluates to " << v1
+      << "\n" << e2 << " evaluates to " << v2
+      << "\n" << e3 << " evaluates to " << v3
+      << "\n" << e4 << " evaluates to " << v4;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT4(pred_format, v1, v2, v3, v4, on_failure)\
+  GTEST_ASSERT(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\
+               on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED4.  Don't use
+// this in your code.
+#define GTEST_PRED4(pred, v1, v2, v3, v4, on_failure)\
+  GTEST_ASSERT(::testing::AssertPred4Helper(#pred, \
+                                 #v1, \
+                                 #v2, \
+                                 #v3, \
+                                 #v4, \
+                                 pred, \
+                                 v1, \
+                                 v2, \
+                                 v3, \
+                                 v4), on_failure)
+
+// 4-ary predicate assertion macros.
+#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
+  GTEST_PRED_FORMAT4(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE)
+#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
+  GTEST_PRED4(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE)
+#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
+  GTEST_PRED_FORMAT4(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE)
+#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
+  GTEST_PRED4(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE)
+
+
+
+// Helper function for implementing {EXPECT|ASSERT}_PRED5.  Don't use
+// this in your code.
+template <typename Pred,
+          typename T1,
+          typename T2,
+          typename T3,
+          typename T4,
+          typename T5>
+AssertionResult AssertPred5Helper(const char* pred_text,
+                                  const char* e1,
+                                  const char* e2,
+                                  const char* e3,
+                                  const char* e4,
+                                  const char* e5,
+                                  Pred pred,
+                                  const T1& v1,
+                                  const T2& v2,
+                                  const T3& v3,
+                                  const T4& v4,
+                                  const T5& v5) {
+  if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
+
+  Message msg;
+  msg << pred_text << "("
+      << e1 << ", "
+      << e2 << ", "
+      << e3 << ", "
+      << e4 << ", "
+      << e5 << ") evaluates to false, where"
+      << "\n" << e1 << " evaluates to " << v1
+      << "\n" << e2 << " evaluates to " << v2
+      << "\n" << e3 << " evaluates to " << v3
+      << "\n" << e4 << " evaluates to " << v4
+      << "\n" << e5 << " evaluates to " << v5;
+  return AssertionFailure(msg);
+}
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
+// Don't use this in your code.
+#define GTEST_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5, on_failure)\
+  GTEST_ASSERT(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\
+               on_failure)
+
+// Internal macro for implementing {EXPECT|ASSERT}_PRED5.  Don't use
+// this in your code.
+#define GTEST_PRED5(pred, v1, v2, v3, v4, v5, on_failure)\
+  GTEST_ASSERT(::testing::AssertPred5Helper(#pred, \
+                                 #v1, \
+                                 #v2, \
+                                 #v3, \
+                                 #v4, \
+                                 #v5, \
+                                 pred, \
+                                 v1, \
+                                 v2, \
+                                 v3, \
+                                 v4, \
+                                 v5), on_failure)
+
+// 5-ary predicate assertion macros.
+#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
+  GTEST_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE)
+#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
+  GTEST_PRED5(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE)
+#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
+  GTEST_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE)
+#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
+  GTEST_PRED5(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE)
+
+
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
diff --git a/src/gtest/gtest_prod.h b/src/gtest/gtest_prod.h
new file mode 100644
index 0000000..da80ddc
--- /dev/null
+++ b/src/gtest/gtest_prod.h
@@ -0,0 +1,58 @@
+// Copyright 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: wan@google.com (Zhanyong Wan)
+//
+// Google C++ Testing Framework definitions useful in production code.
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
+
+// When you need to test the private or protected members of a class,
+// use the FRIEND_TEST macro to declare your tests as friends of the
+// class.  For example:
+//
+// class MyClass {
+//  private:
+//   void MyMethod();
+//   FRIEND_TEST(MyClassTest, MyMethod);
+// };
+//
+// class MyClassTest : public testing::Test {
+//   // ...
+// };
+//
+// TEST_F(MyClassTest, MyMethod) {
+//   // Can call MyClass::MyMethod() here.
+// }
+
+#define FRIEND_TEST(test_case_name, test_name)\
+friend class test_case_name##_##test_name##_Test
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
diff --git a/src/gtest/internal/gtest-death-test-internal.h b/src/gtest/internal/gtest-death-test-internal.h
new file mode 100644
index 0000000..b49c6e4
--- /dev/null
+++ b/src/gtest/internal/gtest-death-test-internal.h
@@ -0,0 +1,201 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file defines internal utilities needed for implementing
+// death tests.  They are subject to change without notice.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+
+#include <gtest/internal/gtest-internal.h>
+
+namespace testing {
+namespace internal {
+
+GTEST_DECLARE_string(internal_run_death_test);
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kDeathTestStyleFlag[] = "death_test_style";
+const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// DeathTest is a class that hides much of the complexity of the
+// GTEST_DEATH_TEST macro.  It is abstract; its static Create method
+// returns a concrete class that depends on the prevailing death test
+// style, as defined by the --gtest_death_test_style and/or
+// --gtest_internal_run_death_test flags.
+
+// In describing the results of death tests, these terms are used with
+// the corresponding definitions:
+//
+// exit status:  The integer exit information in the format specified
+//               by wait(2)
+// exit code:    The integer code passed to exit(3), _exit(2), or
+//               returned from main()
+class DeathTest {
+ public:
+  // Create returns false if there was an error determining the
+  // appropriate action to take for the current death test; for example,
+  // if the gtest_death_test_style flag is set to an invalid value.
+  // The LastMessage method will return a more detailed message in that
+  // case.  Otherwise, the DeathTest pointer pointed to by the "test"
+  // argument is set.  If the death test should be skipped, the pointer
+  // is set to NULL; otherwise, it is set to the address of a new concrete
+  // DeathTest object that controls the execution of the current test.
+  static bool Create(const char* statement, const RE* regex,
+                     const char* file, int line, DeathTest** test);
+  DeathTest();
+  virtual ~DeathTest() { }
+
+  // A helper class that aborts a death test when it's deleted.
+  class ReturnSentinel {
+   public:
+    explicit ReturnSentinel(DeathTest* test) : test_(test) { }
+    ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
+   private:
+    DeathTest* const test_;
+    GTEST_DISALLOW_COPY_AND_ASSIGN(ReturnSentinel);
+  } GTEST_ATTRIBUTE_UNUSED;
+
+  // An enumeration of possible roles that may be taken when a death
+  // test is encountered.  EXECUTE means that the death test logic should
+  // be executed immediately.  OVERSEE means that the program should prepare
+  // the appropriate environment for a child process to execute the death
+  // test, then wait for it to complete.
+  enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
+
+  // An enumeration of the two reasons that a test might be aborted.
+  enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_DID_NOT_DIE };
+
+  // Assumes one of the above roles.
+  virtual TestRole AssumeRole() = 0;
+
+  // Waits for the death test to finish and returns its status.
+  virtual int Wait() = 0;
+
+  // Returns true if the death test passed; that is, the test process
+  // exited during the test, its exit status matches a user-supplied
+  // predicate, and its stderr output matches a user-supplied regular
+  // expression.
+  // The user-supplied predicate may be a macro expression rather
+  // than a function pointer or functor, or else Wait and Passed could
+  // be combined.
+  virtual bool Passed(bool exit_status_ok) = 0;
+
+  // Signals that the death test did not die as expected.
+  virtual void Abort(AbortReason reason) = 0;
+
+  // Returns a human-readable outcome message regarding the outcome of
+  // the last death test.
+  static const char* LastMessage();
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN(DeathTest);
+};
+
+// Factory interface for death tests.  May be mocked out for testing.
+class DeathTestFactory {
+ public:
+  virtual ~DeathTestFactory() { }
+  virtual bool Create(const char* statement, const RE* regex,
+                      const char* file, int line, DeathTest** test) = 0;
+};
+
+// A concrete DeathTestFactory implementation for normal use.
+class DefaultDeathTestFactory : public DeathTestFactory {
+ public:
+  virtual bool Create(const char* statement, const RE* regex,
+                      const char* file, int line, DeathTest** test);
+};
+
+// Returns true if exit_status describes a process that was terminated
+// by a signal, or exited normally with a nonzero exit code.
+bool ExitedUnsuccessfully(int exit_status);
+
+// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
+// ASSERT_EXIT*, and EXPECT_EXIT*.
+#define GTEST_DEATH_TEST(statement, predicate, regex, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER \
+  if (true) { \
+    const ::testing::internal::RE& gtest_regex = (regex); \
+    ::testing::internal::DeathTest* gtest_dt; \
+    if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
+        __FILE__, __LINE__, &gtest_dt)) { \
+      goto GTEST_CONCAT_TOKEN(gtest_label_, __LINE__); \
+    } \
+    if (gtest_dt != NULL) { \
+      ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
+          gtest_dt_ptr(gtest_dt); \
+      switch (gtest_dt->AssumeRole()) { \
+        case ::testing::internal::DeathTest::OVERSEE_TEST: \
+          if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
+            goto GTEST_CONCAT_TOKEN(gtest_label_, __LINE__); \
+          } \
+          break; \
+        case ::testing::internal::DeathTest::EXECUTE_TEST: { \
+          ::testing::internal::DeathTest::ReturnSentinel \
+              gtest_sentinel(gtest_dt); \
+          { statement; } \
+          gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
+          break; \
+        } \
+      } \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN(gtest_label_, __LINE__): \
+      fail(::testing::internal::DeathTest::LastMessage())
+// The symbol "fail" here expands to something into which a message
+// can be streamed.
+
+// A struct representing the parsed contents of the
+// --gtest_internal_run_death_test flag, as it existed when
+// RUN_ALL_TESTS was called.
+struct InternalRunDeathTestFlag {
+  String file;
+  int line;
+  int index;
+  int status_fd;
+};
+
+// Returns a newly created InternalRunDeathTestFlag object with fields
+// initialized from the GTEST_FLAG(internal_run_death_test) flag if
+// the flag is specified; otherwise returns NULL.
+InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
diff --git a/src/gtest/internal/gtest-filepath.h b/src/gtest/internal/gtest-filepath.h
new file mode 100644
index 0000000..6f63718
--- /dev/null
+++ b/src/gtest/internal/gtest-filepath.h
@@ -0,0 +1,168 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: keith.ray@gmail.com (Keith Ray)
+//
+// Google Test filepath utilities
+//
+// This header file declares classes and functions used internally by
+// Google Test.  They are subject to change without notice.
+//
+// This file is #included in testing/base/internal/gtest-internal.h
+// Do not include this header file separately!
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+
+#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+// When using Google Test on the Mac as a framework, all the includes will be
+// in the framework headers folder along with gtest.h.
+// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on
+// the Mac and are not using it as a framework.
+// More info on frameworks available here:
+// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/
+// Concepts/WhatAreFrameworks.html.
+#include "gtest-string.h"  // NOLINT
+#else
+#include <gtest/internal/gtest-string.h>
+#endif  // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+
+
+namespace testing {
+namespace internal {
+
+// FilePath - a class for file and directory pathname manipulation which
+// handles platform-specific conventions (like the pathname separator).
+// Used for helper functions for naming files in a directory for xml output.
+// Except for Set methods, all methods are const or static, which provides an
+// "immutable value object" -- useful for peace of mind.
+// A FilePath with a value ending in a path separator ("like/this/") represents
+// a directory, otherwise it is assumed to represent a file. In either case,
+// it may or may not represent an actual file or directory in the file system.
+// Names are NOT checked for syntax correctness -- no checking for illegal
+// characters, malformed paths, etc.
+
+class FilePath {
+ public:
+  FilePath() : pathname_("") { }
+  FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
+  explicit FilePath(const char* pathname) : pathname_(pathname) { }
+  explicit FilePath(const String& pathname) : pathname_(pathname) { }
+
+  void Set(const FilePath& rhs) {
+    pathname_ = rhs.pathname_;
+  }
+
+  String ToString() const { return pathname_; }
+  const char* c_str() const { return pathname_.c_str(); }
+
+  // Given directory = "dir", base_name = "test", number = 0,
+  // extension = "xml", returns "dir/test.xml". If number is greater
+  // than zero (e.g., 12), returns "dir/test_12.xml".
+  // On Windows platform, uses \ as the separator rather than /.
+  static FilePath MakeFileName(const FilePath& directory,
+                               const FilePath& base_name,
+                               int number,
+                               const char* extension);
+
+  // Returns a pathname for a file that does not currently exist. The pathname
+  // will be directory/base_name.extension or
+  // directory/base_name_<number>.extension if directory/base_name.extension
+  // already exists. The number will be incremented until a pathname is found
+  // that does not already exist.
+  // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
+  // There could be a race condition if two or more processes are calling this
+  // function at the same time -- they could both pick the same filename.
+  static FilePath GenerateUniqueFileName(const FilePath& directory,
+                                         const FilePath& base_name,
+                                         const char* extension);
+
+  // If input name has a trailing separator character, removes it and returns
+  // the name, otherwise return the name string unmodified.
+  // On Windows platform, uses \ as the separator, other platforms use /.
+  FilePath RemoveTrailingPathSeparator() const;
+
+  // Returns a copy of the FilePath with the directory part removed.
+  // Example: FilePath("path/to/file").RemoveDirectoryName() returns
+  // FilePath("file"). If there is no directory part ("just_a_file"), it returns
+  // the FilePath unmodified. If there is no file part ("just_a_dir/") it
+  // returns an empty FilePath ("").
+  // On Windows platform, '\' is the path separator, otherwise it is '/'.
+  FilePath RemoveDirectoryName() const;
+
+  // RemoveFileName returns the directory path with the filename removed.
+  // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
+  // If the FilePath is "a_file" or "/a_file", RemoveFileName returns
+  // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
+  // not have a file, like "just/a/dir/", it returns the FilePath unmodified.
+  // On Windows platform, '\' is the path separator, otherwise it is '/'.
+  FilePath RemoveFileName() const;
+
+  // Returns a copy of the FilePath with the case-insensitive extension removed.
+  // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
+  // FilePath("dir/file"). If a case-insensitive extension is not
+  // found, returns a copy of the original FilePath.
+  FilePath RemoveExtension(const char* extension) const;
+
+  // Creates directories so that path exists. Returns true if successful or if
+  // the directories already exist; returns false if unable to create
+  // directories for any reason. Will also return false if the FilePath does
+  // not represent a directory (that is, it doesn't end with a path separator).
+  bool CreateDirectoriesRecursively() const;
+
+  // Create the directory so that path exists. Returns true if successful or
+  // if the directory already exists; returns false if unable to create the
+  // directory for any reason, including if the parent directory does not
+  // exist. Not named "CreateDirectory" because that's a macro on Windows.
+  bool CreateFolder() const;
+
+  // Returns true if FilePath describes something in the file-system,
+  // either a file, directory, or whatever, and that something exists.
+  bool FileOrDirectoryExists() const;
+
+  // Returns true if pathname describes a directory in the file-system
+  // that exists.
+  bool DirectoryExists() const;
+
+  // Returns true if FilePath ends with a path separator, which indicates that
+  // it is intended to represent a directory. Returns false otherwise.
+  // This does NOT check that a directory (or file) actually exists.
+  bool IsDirectory() const;
+
+ private:
+  String pathname_;
+
+  // Don't implement operator= because it is banned by the style guide.
+  FilePath& operator=(const FilePath& rhs);
+};  // class FilePath
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
diff --git a/src/gtest/internal/gtest-internal.h b/src/gtest/internal/gtest-internal.h
new file mode 100644
index 0000000..2be1b4a
--- /dev/null
+++ b/src/gtest/internal/gtest-internal.h
@@ -0,0 +1,569 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file declares functions and macros used internally by
+// Google Test.  They are subject to change without notice.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+
+#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+// When using Google Test on the Mac as a framework, all the includes will be
+// in the framework headers folder along with gtest.h.
+// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on
+// the Mac and are not using it as a framework.
+// More info on frameworks available here:
+// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/
+// Concepts/WhatAreFrameworks.html.
+#include "gtest-port.h"  // NOLINT
+#else
+#include <gtest/internal/gtest-port.h>
+#endif  // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+
+#ifdef GTEST_OS_LINUX
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#endif  // GTEST_OS_LINUX
+
+#include <iomanip>  // NOLINT
+#include <limits>   // NOLINT
+
+#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+// When using Google Test on the Mac as a framework, all the includes will be
+// in the framework headers folder along with gtest.h.
+// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on
+// the Mac and are not using it as a framework.
+// More info on frameworks available here:
+// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/
+// Concepts/WhatAreFrameworks.html.
+#include "gtest-string.h"  // NOLINT
+#include "gtest-filepath.h"  // NOLINT
+#else
+#include <gtest/internal/gtest-string.h>
+#include <gtest/internal/gtest-filepath.h>
+#endif  // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+
+// Due to C++ preprocessor weirdness, we need double indirection to
+// concatenate two tokens when one of them is __LINE__.  Writing
+//
+//   foo ## __LINE__
+//
+// will result in the token foo__LINE__, instead of foo followed by
+// the current line number.  For more details, see
+// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
+#define GTEST_CONCAT_TOKEN(foo, bar) GTEST_CONCAT_TOKEN_IMPL(foo, bar)
+#define GTEST_CONCAT_TOKEN_IMPL(foo, bar) foo ## bar
+
+// Google Test defines the testing::Message class to allow construction of
+// test messages via the << operator.  The idea is that anything
+// streamable to std::ostream can be streamed to a testing::Message.
+// This allows a user to use his own types in Google Test assertions by
+// overloading the << operator.
+//
+// util/gtl/stl_logging-inl.h overloads << for STL containers.  These
+// overloads cannot be defined in the std namespace, as that will be
+// undefined behavior.  Therefore, they are defined in the global
+// namespace instead.
+//
+// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
+// overloads are visible in either the std namespace or the global
+// namespace, but not other namespaces, including the testing
+// namespace which Google Test's Message class is in.
+//
+// To allow STL containers (and other types that has a << operator
+// defined in the global namespace) to be used in Google Test assertions,
+// testing::Message must access the custom << operator from the global
+// namespace.  Hence this helper function.
+//
+// Note: Jeffrey Yasskin suggested an alternative fix by "using
+// ::operator<<;" in the definition of Message's operator<<.  That fix
+// doesn't require a helper function, but unfortunately doesn't
+// compile with MSVC.
+template <typename T>
+inline void GTestStreamToHelper(std::ostream* os, const T& val) {
+  *os << val;
+}
+
+namespace testing {
+
+// Forward declaration of classes.
+
+class Message;                         // Represents a failure message.
+class TestCase;                        // A collection of related tests.
+class TestPartResult;                  // Result of a test part.
+class TestInfo;                        // Information about a test.
+class UnitTest;                        // A collection of test cases.
+class UnitTestEventListenerInterface;  // Listens to Google Test events.
+class AssertionResult;                 // Result of an assertion.
+
+namespace internal {
+
+struct TraceInfo;                      // Information about a trace point.
+class ScopedTrace;                     // Implements scoped trace.
+class TestInfoImpl;                    // Opaque implementation of TestInfo
+class TestResult;                      // Result of a single Test.
+class UnitTestImpl;                    // Opaque implementation of UnitTest
+
+template <typename E> class List;      // A generic list.
+template <typename E> class ListNode;  // A node in a generic list.
+
+// A secret type that Google Test users don't know about.  It has no
+// definition on purpose.  Therefore it's impossible to create a
+// Secret object, which is what we want.
+class Secret;
+
+// Two overloaded helpers for checking at compile time whether an
+// expression is a null pointer literal (i.e. NULL or any 0-valued
+// compile-time integral constant).  Their return values have
+// different sizes, so we can use sizeof() to test which version is
+// picked by the compiler.  These helpers have no implementations, as
+// we only need their signatures.
+//
+// Given IsNullLiteralHelper(x), the compiler will pick the first
+// version if x can be implicitly converted to Secret*, and pick the
+// second version otherwise.  Since Secret is a secret and incomplete
+// type, the only expression a user can write that has type Secret* is
+// a null pointer literal.  Therefore, we know that x is a null
+// pointer literal if and only if the first version is picked by the
+// compiler.
+char IsNullLiteralHelper(Secret* p);
+char (&IsNullLiteralHelper(...))[2];  // NOLINT
+
+// A compile-time bool constant that is true if and only if x is a
+// null pointer literal (i.e. NULL or any 0-valued compile-time
+// integral constant).
+#ifdef __SYMBIAN32__  // Symbian
+// Passing non-POD classes through ellipsis (...) crashes the ARM compiler.
+// The Nokia Symbian compiler tries to instantiate a copy constructor for
+// objects passed through ellipsis (...), failing for uncopyable objects.
+// Hence we define this to false (and lose support for NULL detection).
+#define GTEST_IS_NULL_LITERAL(x) false
+#else  // ! __SYMBIAN32__
+#define GTEST_IS_NULL_LITERAL(x) \
+    (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)
+#endif  // __SYMBIAN32__
+
+// Appends the user-supplied message to the Google-Test-generated message.
+String AppendUserMessage(const String& gtest_msg,
+                         const Message& user_msg);
+
+// A helper class for creating scoped traces in user programs.
+class ScopedTrace {
+ public:
+  // The c'tor pushes the given source file location and message onto
+  // a trace stack maintained by Google Test.
+  ScopedTrace(const char* file, int line, const Message& message);
+
+  // The d'tor pops the info pushed by the c'tor.
+  //
+  // Note that the d'tor is not virtual in order to be efficient.
+  // Don't inherit from ScopedTrace!
+  ~ScopedTrace();
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN(ScopedTrace);
+} GTEST_ATTRIBUTE_UNUSED;  // A ScopedTrace object does its job in its
+                           // c'tor and d'tor.  Therefore it doesn't
+                           // need to be used otherwise.
+
+// Converts a streamable value to a String.  A NULL pointer is
+// converted to "(null)".  When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+// Declared here but defined in gtest.h, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable);
+
+// Formats a value to be used in a failure message.
+
+#ifdef __SYMBIAN32__
+
+// These are needed as the Nokia Symbian Compiler cannot decide between
+// const T& and const T* in a function template. The Nokia compiler _can_
+// decide between class template specializations for T and T*, so a
+// tr1::type_traits-like is_pointer works, and we can overload on that.
+
+// This overload makes sure that all pointers (including
+// those to char or wchar_t) are printed as raw pointers.
+template <typename T>
+inline String FormatValueForFailureMessage(internal::true_type dummy,
+                                           T* pointer) {
+  return StreamableToString(static_cast<const void*>(pointer));
+}
+
+template <typename T>
+inline String FormatValueForFailureMessage(internal::false_type dummy,
+                                           const T& value) {
+  return StreamableToString(value);
+}
+
+template <typename T>
+inline String FormatForFailureMessage(const T& value) {
+  return FormatValueForFailureMessage(
+      typename internal::is_pointer<T>::type(), value);
+}
+
+#else
+
+template <typename T>
+inline String FormatForFailureMessage(const T& value) {
+  return StreamableToString(value);
+}
+
+// This overload makes sure that all pointers (including
+// those to char or wchar_t) are printed as raw pointers.
+template <typename T>
+inline String FormatForFailureMessage(T* pointer) {
+  return StreamableToString(static_cast<const void*>(pointer));
+}
+
+#endif  // __SYMBIAN32__
+
+// These overloaded versions handle narrow and wide characters.
+String FormatForFailureMessage(char ch);
+String FormatForFailureMessage(wchar_t wchar);
+
+// When this operand is a const char* or char*, and the other operand
+// is a ::std::string or ::string, we print this operand as a C string
+// rather than a pointer.  We do the same for wide strings.
+
+// This internal macro is used to avoid duplicated code.
+#define GTEST_FORMAT_IMPL(operand2_type, operand1_printer)\
+inline String FormatForComparisonFailureMessage(\
+    operand2_type::value_type* str, const operand2_type& operand2) {\
+  return operand1_printer(str);\
+}\
+inline String FormatForComparisonFailureMessage(\
+    const operand2_type::value_type* str, const operand2_type& operand2) {\
+  return operand1_printer(str);\
+}
+
+#if GTEST_HAS_STD_STRING
+GTEST_FORMAT_IMPL(::std::string, String::ShowCStringQuoted)
+#endif  // GTEST_HAS_STD_STRING
+#if GTEST_HAS_STD_WSTRING
+GTEST_FORMAT_IMPL(::std::wstring, String::ShowWideCStringQuoted)
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_STRING
+GTEST_FORMAT_IMPL(::string, String::ShowCStringQuoted)
+#endif  // GTEST_HAS_GLOBAL_STRING
+#if GTEST_HAS_GLOBAL_WSTRING
+GTEST_FORMAT_IMPL(::wstring, String::ShowWideCStringQuoted)
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+#undef GTEST_FORMAT_IMPL
+
+// Constructs and returns the message for an equality assertion
+// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.
+//
+// The first four parameters are the expressions used in the assertion
+// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)
+// where foo is 5 and bar is 6, we have:
+//
+//   expected_expression: "foo"
+//   actual_expression:   "bar"
+//   expected_value:      "5"
+//   actual_value:        "6"
+//
+// The ignoring_case parameter is true iff the assertion is a
+// *_STRCASEEQ*.  When it's true, the string " (ignoring case)" will
+// be inserted into the message.
+AssertionResult EqFailure(const char* expected_expression,
+                          const char* actual_expression,
+                          const String& expected_value,
+                          const String& actual_value,
+                          bool ignoring_case);
+
+
+// This template class represents an IEEE floating-point number
+// (either single-precision or double-precision, depending on the
+// template parameters).
+//
+// The purpose of this class is to do more sophisticated number
+// comparison.  (Due to round-off error, etc, it's very unlikely that
+// two floating-points will be equal exactly.  Hence a naive
+// comparison by the == operation often doesn't work.)
+//
+// Format of IEEE floating-point:
+//
+//   The most-significant bit being the leftmost, an IEEE
+//   floating-point looks like
+//
+//     sign_bit exponent_bits fraction_bits
+//
+//   Here, sign_bit is a single bit that designates the sign of the
+//   number.
+//
+//   For float, there are 8 exponent bits and 23 fraction bits.
+//
+//   For double, there are 11 exponent bits and 52 fraction bits.
+//
+//   More details can be found at
+//   http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
+//
+// Template parameter:
+//
+//   RawType: the raw floating-point type (either float or double)
+template <typename RawType>
+class FloatingPoint {
+ public:
+  // Defines the unsigned integer type that has the same size as the
+  // floating point number.
+  typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;
+
+  // Constants.
+
+  // # of bits in a number.
+  static const size_t kBitCount = 8*sizeof(RawType);
+
+  // # of fraction bits in a number.
+  static const size_t kFractionBitCount =
+    std::numeric_limits<RawType>::digits - 1;
+
+  // # of exponent bits in a number.
+  static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;
+
+  // The mask for the sign bit.
+  static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
+
+  // The mask for the fraction bits.
+  static const Bits kFractionBitMask =
+    ~static_cast<Bits>(0) >> (kExponentBitCount + 1);
+
+  // The mask for the exponent bits.
+  static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);
+
+  // How many ULP's (Units in the Last Place) we want to tolerate when
+  // comparing two numbers.  The larger the value, the more error we
+  // allow.  A 0 value means that two numbers must be exactly the same
+  // to be considered equal.
+  //
+  // The maximum error of a single floating-point operation is 0.5
+  // units in the last place.  On Intel CPU's, all floating-point
+  // calculations are done with 80-bit precision, while double has 64
+  // bits.  Therefore, 4 should be enough for ordinary use.
+  //
+  // See the following article for more details on ULP:
+  // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm.
+  static const size_t kMaxUlps = 4;
+
+  // Constructs a FloatingPoint from a raw floating-point number.
+  //
+  // On an Intel CPU, passing a non-normalized NAN (Not a Number)
+  // around may change its bits, although the new value is guaranteed
+  // to be also a NAN.  Therefore, don't expect this constructor to
+  // preserve the bits in x when x is a NAN.
+  explicit FloatingPoint(const RawType& x) : value_(x) {}
+
+  // Static methods
+
+  // Reinterprets a bit pattern as a floating-point number.
+  //
+  // This function is needed to test the AlmostEquals() method.
+  static RawType ReinterpretBits(const Bits bits) {
+    FloatingPoint fp(0);
+    fp.bits_ = bits;
+    return fp.value_;
+  }
+
+  // Returns the floating-point number that represent positive infinity.
+  static RawType Infinity() {
+    return ReinterpretBits(kExponentBitMask);
+  }
+
+  // Non-static methods
+
+  // Returns the bits that represents this number.
+  const Bits &bits() const { return bits_; }
+
+  // Returns the exponent bits of this number.
+  Bits exponent_bits() const { return kExponentBitMask & bits_; }
+
+  // Returns the fraction bits of this number.
+  Bits fraction_bits() const { return kFractionBitMask & bits_; }
+
+  // Returns the sign bit of this number.
+  Bits sign_bit() const { return kSignBitMask & bits_; }
+
+  // Returns true iff this is NAN (not a number).
+  bool is_nan() const {
+    // It's a NAN if the exponent bits are all ones and the fraction
+    // bits are not entirely zeros.
+    return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
+  }
+
+  // Returns true iff this number is at most kMaxUlps ULP's away from
+  // rhs.  In particular, this function:
+  //
+  //   - returns false if either number is (or both are) NAN.
+  //   - treats really large numbers as almost equal to infinity.
+  //   - thinks +0.0 and -0.0 are 0 DLP's apart.
+  bool AlmostEquals(const FloatingPoint& rhs) const {
+    // The IEEE standard says that any comparison operation involving
+    // a NAN must return false.
+    if (is_nan() || rhs.is_nan()) return false;
+
+    return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
+  }
+
+ private:
+  // Converts an integer from the sign-and-magnitude representation to
+  // the biased representation.  More precisely, let N be 2 to the
+  // power of (kBitCount - 1), an integer x is represented by the
+  // unsigned number x + N.
+  //
+  // For instance,
+  //
+  //   -N + 1 (the most negative number representable using
+  //          sign-and-magnitude) is represented by 1;
+  //   0      is represented by N; and
+  //   N - 1  (the biggest number representable using
+  //          sign-and-magnitude) is represented by 2N - 1.
+  //
+  // Read http://en.wikipedia.org/wiki/Signed_number_representations
+  // for more details on signed number representations.
+  static Bits SignAndMagnitudeToBiased(const Bits &sam) {
+    if (kSignBitMask & sam) {
+      // sam represents a negative number.
+      return ~sam + 1;
+    } else {
+      // sam represents a positive number.
+      return kSignBitMask | sam;
+    }
+  }
+
+  // Given two numbers in the sign-and-magnitude representation,
+  // returns the distance between them as an unsigned number.
+  static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1,
+                                                     const Bits &sam2) {
+    const Bits biased1 = SignAndMagnitudeToBiased(sam1);
+    const Bits biased2 = SignAndMagnitudeToBiased(sam2);
+    return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
+  }
+
+  union {
+    RawType value_;  // The raw floating-point number.
+    Bits bits_;      // The bits that represent the number.
+  };
+};
+
+// Typedefs the instances of the FloatingPoint template class that we
+// care to use.
+typedef FloatingPoint<float> Float;
+typedef FloatingPoint<double> Double;
+
+// In order to catch the mistake of putting tests that use different
+// test fixture classes in the same test case, we need to assign
+// unique IDs to fixture classes and compare them.  The TypeId type is
+// used to hold such IDs.  The user should treat TypeId as an opaque
+// type: the only operation allowed on TypeId values is to compare
+// them for equality using the == operator.
+typedef void* TypeId;
+
+// GetTypeId<T>() returns the ID of type T.  Different values will be
+// returned for different types.  Calling the function twice with the
+// same type argument is guaranteed to return the same ID.
+template <typename T>
+inline TypeId GetTypeId() {
+  static bool dummy = false;
+  // The compiler is required to create an instance of the static
+  // variable dummy for each T used to instantiate the template.
+  // Therefore, the address of dummy is guaranteed to be unique.
+  return &dummy;
+}
+
+#ifdef GTEST_OS_WINDOWS
+
+// Predicate-formatters for implementing the HRESULT checking macros
+// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}
+// We pass a long instead of HRESULT to avoid causing an
+// include dependency for the HRESULT type.
+AssertionResult IsHRESULTSuccess(const char* expr, long hr);  // NOLINT
+AssertionResult IsHRESULTFailure(const char* expr, long hr);  // NOLINT
+
+#endif  // GTEST_OS_WINDOWS
+
+}  // namespace internal
+}  // namespace testing
+
+#define GTEST_MESSAGE(message, result_type) \
+  ::testing::internal::AssertHelper(result_type, __FILE__, __LINE__, message) \
+    = ::testing::Message()
+
+#define GTEST_FATAL_FAILURE(message) \
+  return GTEST_MESSAGE(message, ::testing::TPRT_FATAL_FAILURE)
+
+#define GTEST_NONFATAL_FAILURE(message) \
+  GTEST_MESSAGE(message, ::testing::TPRT_NONFATAL_FAILURE)
+
+#define GTEST_SUCCESS(message) \
+  GTEST_MESSAGE(message, ::testing::TPRT_SUCCESS)
+
+#define GTEST_TEST_BOOLEAN(boolexpr, booltext, actual, expected, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER \
+  if (boolexpr) \
+    ; \
+  else \
+    fail("Value of: " booltext "\n  Actual: " #actual "\nExpected: " #expected)
+
+// Helper macro for defining tests.
+#define GTEST_TEST(test_case_name, test_name, parent_class)\
+class test_case_name##_##test_name##_Test : public parent_class {\
+ public:\
+  test_case_name##_##test_name##_Test() {}\
+  static ::testing::Test* NewTest() {\
+    return new test_case_name##_##test_name##_Test;\
+  }\
+ private:\
+  virtual void TestBody();\
+  static ::testing::TestInfo* const test_info_;\
+  GTEST_DISALLOW_COPY_AND_ASSIGN(test_case_name##_##test_name##_Test);\
+};\
+\
+::testing::TestInfo* const test_case_name##_##test_name##_Test::test_info_ =\
+  ::testing::TestInfo::MakeAndRegisterInstance(\
+    #test_case_name, \
+    #test_name, \
+    ::testing::internal::GetTypeId< parent_class >(), \
+    parent_class::SetUpTestCase, \
+    parent_class::TearDownTestCase, \
+    test_case_name##_##test_name##_Test::NewTest);\
+void test_case_name##_##test_name##_Test::TestBody()
+
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
diff --git a/src/gtest/internal/gtest-port.h b/src/gtest/internal/gtest-port.h
new file mode 100644
index 0000000..36d5a14
--- /dev/null
+++ b/src/gtest/internal/gtest-port.h
@@ -0,0 +1,596 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan)
+//
+// Low-level types and utilities for porting Google Test to various
+// platforms.  They are subject to change without notice.  DO NOT USE
+// THEM IN USER CODE.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
+
+#ifndef GTEST_NOT_MAC_FRAMEWORK_MODE
+// Protobuf never uses gTest in "mac framework mode".
+#define GTEST_NOT_MAC_FRAMEWORK_MODE
+#endif
+
+// The user can define the following macros in the build script to
+// control Google Test's behavior:
+//
+//   GTEST_HAS_STD_STRING    - Define it to 1/0 to indicate that
+//                             std::string does/doesn't work (Google Test can be
+//                             used where std::string is unavailable).  Leave
+//                             it undefined to let Google Test define it.
+//   GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string
+//                             is/isn't available (some systems define ::string,
+//                             which is different to std::string).  Leave it
+//                             undefined to let Google Test define it.
+
+// This header defines the following utilities:
+//
+// Macros indicating the name of the Google C++ Testing Framework project:
+//   GTEST_NAME              - a string literal of the project name.
+//   GTEST_FLAG_PREFIX       - a string literal of the prefix all Google
+//                             Test flag names share.
+//   GTEST_FLAG_PREFIX_UPPER - a string literal of the prefix all Google
+//                             Test flag names share, in upper case.
+//
+// Macros indicating the current platform:
+//   GTEST_OS_LINUX    - defined iff compiled on Linux.
+//   GTEST_OS_MAC      - defined iff compiled on Mac OS X.
+//   GTEST_OS_WINDOWS  - defined iff compiled on Windows.
+// Note that it is possible that none of the GTEST_OS_ macros are defined.
+//
+// Macros indicating available Google Test features:
+//   GTEST_HAS_DEATH_TEST  - defined iff death tests are supported.
+//
+// Macros for basic C++ coding:
+//   GTEST_AMBIGUOUS_ELSE_BLOCKER - for disabling a gcc warning.
+//   GTEST_ATTRIBUTE_UNUSED  - declares that a class' instances don't have to
+//                             be used.
+//   GTEST_DISALLOW_COPY_AND_ASSIGN()  - disables copy ctor and operator=.
+//   GTEST_MUST_USE_RESULT   - declares that a function's result must be used.
+//
+// Synchronization:
+//   Mutex, MutexLock, ThreadLocal, GetThreadCount()
+//                  - synchronization primitives.
+//
+// Template meta programming:
+//   is_pointer     - as in TR1; needed on Symbian only.
+//
+// Smart pointers:
+//   scoped_ptr     - as in TR2.
+//
+// Regular expressions:
+//   RE             - a simple regular expression class using the POSIX
+//                    Extended Regular Expression syntax.  Not available on
+//                    Windows.
+//
+// Logging:
+//   GTEST_LOG()    - logs messages at the specified severity level.
+//   LogToStderr()  - directs all log messages to stderr.
+//   FlushInfoLog() - flushes informational log messages.
+//
+// Stderr capturing:
+//   CaptureStderr()     - starts capturing stderr.
+//   GetCapturedStderr() - stops capturing stderr and returns the captured
+//                         string.
+//
+// Integer types:
+//   TypeWithSize   - maps an integer to a int type.
+//   Int32, UInt32, Int64, UInt64, TimeInMillis
+//                  - integers of known sizes.
+//   BiggestInt     - the biggest signed integer type.
+//
+// Command-line utilities:
+//   GTEST_FLAG()       - references a flag.
+//   GTEST_DECLARE_*()  - declares a flag.
+//   GTEST_DEFINE_*()   - defines a flag.
+//   GetArgvs()         - returns the command line as a vector of strings.
+//
+// Environment variable utilities:
+//   GetEnv()             - gets the value of an environment variable.
+//   BoolFromGTestEnv()   - parses a bool environment variable.
+//   Int32FromGTestEnv()  - parses an Int32 environment variable.
+//   StringFromGTestEnv() - parses a string environment variable.
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define GTEST_NAME "Google Test"
+#define GTEST_FLAG_PREFIX "gtest_"
+#define GTEST_FLAG_PREFIX_UPPER "GTEST_"
+
+// Determines the platform on which Google Test is compiled.
+#ifdef _MSC_VER
+// TODO(kenton):  GTEST_OS_WINDOWS is currently used to mean both "The OS is
+//   Windows" and "The compiler is MSVC".  These meanings really should be
+//   separated in order to better support Windows compilers other than MSVC.
+//   Then again, the macro _WIN32 is already a good way to check for the first
+//   case and _MSC_VER is a good way to check for the latter, so maybe
+//   GTEST_OS_WINDOWS should be removed?
+#define GTEST_OS_WINDOWS
+#elif defined __APPLE__
+#define GTEST_OS_MAC
+#elif defined __linux__
+#define GTEST_OS_LINUX
+#endif  // _MSC_VER
+
+// Determines whether ::std::string and ::string are available.
+
+#ifndef GTEST_HAS_STD_STRING
+// The user didn't tell us whether ::std::string is available, so we
+// need to figure it out.
+
+#ifdef GTEST_OS_WINDOWS
+// Assumes that exceptions are enabled by default.
+#ifndef _HAS_EXCEPTIONS
+#define _HAS_EXCEPTIONS 1
+#endif  // _HAS_EXCEPTIONS
+// GTEST_HAS_EXCEPTIONS is non-zero iff exceptions are enabled.  It is
+// always defined, while _HAS_EXCEPTIONS is defined only on Windows.
+#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
+// On Windows, we can use ::std::string if the compiler version is VS
+// 2005 or above, or if exceptions are enabled.
+#define GTEST_HAS_STD_STRING ((_MSC_VER >= 1400) || GTEST_HAS_EXCEPTIONS)
+#else  // We are on Linux or Mac OS.
+#define GTEST_HAS_EXCEPTIONS 0
+#define GTEST_HAS_STD_STRING 1
+#endif  // GTEST_OS_WINDOWS
+
+#endif  // GTEST_HAS_STD_STRING
+
+#ifndef GTEST_HAS_GLOBAL_STRING
+// The user didn't tell us whether ::string is available, so we need
+// to figure it out.
+
+#define GTEST_HAS_GLOBAL_STRING 0
+
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING
+#include <string>  // NOLINT
+#endif  // GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_STD_STRING
+#include <sstream>  // NOLINT
+#else
+#include <strstream>  // NOLINT
+#endif  // GTEST_HAS_STD_STRING
+
+// Determines whether to support death tests.
+#if GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX)
+#define GTEST_HAS_DEATH_TEST
+// On some platforms, <regex.h> needs someone to define size_t, and
+// won't compile if being #included first.  Therefore it's important
+// that we #include it after <sys/types.h>.
+#include <regex.h>
+#include <vector>
+#include <fcntl.h>
+#include <sys/mman.h>
+#endif  // GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX)
+
+// Defines some utility macros.
+
+// The GNU compiler emits a warning if nested "if" statements are followed by
+// an "else" statement and braces are not used to explicitly disambiguate the
+// "else" binding.  This leads to problems with code like:
+//
+//   if (gate)
+//     ASSERT_*(condition) << "Some message";
+//
+// The "switch (0) case 0:" idiom is used to suppress this.
+#ifdef __INTEL_COMPILER
+#define GTEST_AMBIGUOUS_ELSE_BLOCKER
+#else
+#define GTEST_AMBIGUOUS_ELSE_BLOCKER switch (0) case 0:  // NOLINT
+#endif
+
+// Use this annotation at the end of a struct / class definition to
+// prevent the compiler from optimizing away instances that are never
+// used.  This is useful when all interesting logic happens inside the
+// c'tor and / or d'tor.  Example:
+//
+//   struct Foo {
+//     Foo() { ... }
+//   } GTEST_ATTRIBUTE_UNUSED;
+#if defined(GTEST_OS_WINDOWS) || (defined(GTEST_OS_LINUX) && defined(SWIG))
+#define GTEST_ATTRIBUTE_UNUSED
+#else
+#define GTEST_ATTRIBUTE_UNUSED __attribute__ ((unused))
+#endif  // GTEST_OS_WINDOWS || (GTEST_OS_LINUX && SWIG)
+
+// A macro to disallow the evil copy constructor and operator= functions
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_COPY_AND_ASSIGN(type)\
+  type(const type &);\
+  void operator=(const type &)
+
+// Tell the compiler to warn about unused return values for functions declared
+// with this macro.  The macro should be used on function declarations
+// following the argument list:
+//
+//   Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT;
+#if defined(__GNUC__) \
+  && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
+  && !defined(COMPILER_ICC)
+#define GTEST_MUST_USE_RESULT __attribute__ ((warn_unused_result))
+#else
+#define GTEST_MUST_USE_RESULT
+#endif  // (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+
+namespace testing {
+
+class Message;
+
+namespace internal {
+
+class String;
+
+// std::strstream is deprecated.  However, we have to use it on
+// Windows as std::stringstream won't compile on Windows when
+// exceptions are disabled.  We use std::stringstream on other
+// platforms to avoid compiler warnings there.
+#if GTEST_HAS_STD_STRING
+typedef ::std::stringstream StrStream;
+#else
+typedef ::std::strstream StrStream;
+#endif  // GTEST_HAS_STD_STRING
+
+// Defines scoped_ptr.
+
+// This implementation of scoped_ptr is PARTIAL - it only contains
+// enough stuff to satisfy Google Test's need.
+template <typename T>
+class scoped_ptr {
+ public:
+  explicit scoped_ptr(T* p = NULL) : ptr_(p) {}
+  ~scoped_ptr() { reset(); }
+
+  T& operator*() const { return *ptr_; }
+  T* operator->() const { return ptr_; }
+  T* get() const { return ptr_; }
+
+  T* release() {
+    T* const ptr = ptr_;
+    ptr_ = NULL;
+    return ptr;
+  }
+
+  void reset(T* p = NULL) {
+    if (p != ptr_) {
+      if (sizeof(T) > 0) {  // Makes sure T is a complete type.
+        delete ptr_;
+      }
+      ptr_ = p;
+    }
+  }
+ private:
+  T* ptr_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN(scoped_ptr);
+};
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// Defines RE.  Currently only needed for death tests.
+
+// A simple C++ wrapper for <regex.h>.  It uses the POSIX Enxtended
+// Regular Expression syntax.
+class RE {
+ public:
+  // Constructs an RE from a string.
+#if GTEST_HAS_STD_STRING
+  RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT
+#endif  // GTEST_HAS_STD_STRING
+
+#if GTEST_HAS_GLOBAL_STRING
+  RE(const ::string& regex) { Init(regex.c_str()); }  // NOLINT
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  RE(const char* regex) { Init(regex); }  // NOLINT
+  ~RE();
+
+  // Returns the string representation of the regex.
+  const char* pattern() const { return pattern_; }
+
+  // Returns true iff str contains regular expression re.
+
+  // TODO(wan): make PartialMatch() work when str contains NUL
+  // characters.
+#if GTEST_HAS_STD_STRING
+  static bool PartialMatch(const ::std::string& str, const RE& re) {
+    return PartialMatch(str.c_str(), re);
+  }
+#endif  // GTEST_HAS_STD_STRING
+
+#if GTEST_HAS_GLOBAL_STRING
+  static bool PartialMatch(const ::string& str, const RE& re) {
+    return PartialMatch(str.c_str(), re);
+  }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  static bool PartialMatch(const char* str, const RE& re);
+
+ private:
+  void Init(const char* regex);
+
+  // We use a const char* instead of a string, as Google Test may be used
+  // where string is not available.  We also do not use Google Test's own
+  // String type here, in order to simplify dependencies between the
+  // files.
+  const char* pattern_;
+  regex_t regex_;
+  bool is_valid_;
+};
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Defines logging utilities:
+//   GTEST_LOG()    - logs messages at the specified severity level.
+//   LogToStderr()  - directs all log messages to stderr.
+//   FlushInfoLog() - flushes informational log messages.
+
+enum GTestLogSeverity {
+  GTEST_INFO,
+  GTEST_WARNING,
+  GTEST_ERROR,
+  GTEST_FATAL
+};
+
+void GTestLog(GTestLogSeverity severity, const char* file,
+              int line, const char* msg);
+
+#define GTEST_LOG(severity, msg)\
+    ::testing::internal::GTestLog(\
+        ::testing::internal::GTEST_##severity, __FILE__, __LINE__, \
+        (::testing::Message() << (msg)).GetString().c_str())
+
+inline void LogToStderr() {}
+inline void FlushInfoLog() { fflush(NULL); }
+
+// Defines the stderr capturer:
+//   CaptureStderr     - starts capturing stderr.
+//   GetCapturedStderr - stops capturing stderr and returns the captured string.
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments.  Set by ParseGTestFlags().
+extern ::std::vector<String> g_argvs;
+
+void CaptureStderr();
+// GTEST_HAS_DEATH_TEST implies we have ::std::string.
+::std::string GetCapturedStderr();
+const ::std::vector<String>& GetArgvs();
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Defines synchronization primitives.
+
+// A dummy implementation of synchronization primitives (mutex, lock,
+// and thread-local variable).  Necessary for compiling Google Test where
+// mutex is not supported - using Google Test in multiple threads is not
+// supported on such platforms.
+
+class Mutex {
+ public:
+  Mutex() {}
+  explicit Mutex(int unused) {}
+  void AssertHeld() const {}
+  enum { NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX = 0 };
+};
+
+// We cannot call it MutexLock directly as the ctor declaration would
+// conflict with a macro named MutexLock, which is defined on some
+// platforms.  Hence the typedef trick below.
+class GTestMutexLock {
+ public:
+  explicit GTestMutexLock(Mutex*) {}  // NOLINT
+};
+
+typedef GTestMutexLock MutexLock;
+
+template <typename T>
+class ThreadLocal {
+ public:
+  T* pointer() { return &value_; }
+  const T* pointer() const { return &value_; }
+  const T& get() const { return value_; }
+  void set(const T& value) { value_ = value; }
+ private:
+  T value_;
+};
+
+// There's no portable way to detect the number of threads, so we just
+// return 0 to indicate that we cannot detect it.
+// CHANGED FOR PROTOBUF:  The protobuf tests do not use multiple threads,
+// so we know there is one thread.
+inline size_t GetThreadCount() { return 1; }
+
+// Defines tr1::is_pointer (only needed for Symbian).
+
+#ifdef __SYMBIAN32__
+
+// Symbian does not have tr1::type_traits, so we define our own is_pointer
+// These are needed as the Nokia Symbian Compiler cannot decide between
+// const T& and const T* in a function template.
+
+template <bool bool_value>
+struct bool_constant {
+  typedef bool_constant<bool_value> type;
+  static const bool value = bool_value;
+};
+template <bool bool_value> const bool bool_constant<bool_value>::value;
+
+typedef bool_constant<false> false_type;
+typedef bool_constant<true> true_type;
+
+template <typename T>
+struct is_pointer : public false_type {};
+
+template <typename T>
+struct is_pointer<T*> : public true_type {};
+
+#endif  // __SYMBIAN32__
+
+// Defines BiggestInt as the biggest signed integer type the compiler
+// supports.
+
+#ifdef GTEST_OS_WINDOWS
+typedef __int64 BiggestInt;
+#else
+typedef long long BiggestInt;  // NOLINT
+#endif  // GTEST_OS_WINDOWS
+
+// The maximum number a BiggestInt can represent.  This definition
+// works no matter BiggestInt is represented in one's complement or
+// two's complement.
+//
+// We cannot rely on numeric_limits in STL, as __int64 and long long
+// are not part of standard C++ and numeric_limits doesn't need to be
+// defined for them.
+const BiggestInt kMaxBiggestInt =
+    ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1));
+
+// This template class serves as a compile-time function from size to
+// type.  It maps a size in bytes to a primitive type with that
+// size. e.g.
+//
+//   TypeWithSize<4>::UInt
+//
+// is typedef-ed to be unsigned int (unsigned integer made up of 4
+// bytes).
+//
+// Such functionality should belong to STL, but I cannot find it
+// there.
+//
+// Google Test uses this class in the implementation of floating-point
+// comparison.
+//
+// For now it only handles UInt (unsigned int) as that's all Google Test
+// needs.  Other types can be easily added in the future if need
+// arises.
+template <size_t size>
+class TypeWithSize {
+ public:
+  // This prevents the user from using TypeWithSize<N> with incorrect
+  // values of N.
+  typedef void UInt;
+};
+
+// The specialization for size 4.
+template <>
+class TypeWithSize<4> {
+ public:
+  // unsigned int has size 4 in both gcc and MSVC.
+  //
+  // As base/basictypes.h doesn't compile on Windows, we cannot use
+  // uint32, uint64, and etc here.
+  typedef int Int;
+  typedef unsigned int UInt;
+};
+
+// The specialization for size 8.
+template <>
+class TypeWithSize<8> {
+ public:
+#ifdef GTEST_OS_WINDOWS
+  typedef __int64 Int;
+  typedef unsigned __int64 UInt;
+#else
+  typedef long long Int;  // NOLINT
+  typedef unsigned long long UInt;  // NOLINT
+#endif  // GTEST_OS_WINDOWS
+};
+
+// Integer types of known sizes.
+typedef TypeWithSize<4>::Int Int32;
+typedef TypeWithSize<4>::UInt UInt32;
+typedef TypeWithSize<8>::Int Int64;
+typedef TypeWithSize<8>::UInt UInt64;
+typedef TypeWithSize<8>::Int TimeInMillis;  // Represents time in milliseconds.
+
+// Utilities for command line flags and environment variables.
+
+// A wrapper for getenv() that works on Linux, Windows, and Mac OS.
+inline const char* GetEnv(const char* name) {
+#ifdef _WIN32_WCE  // We are on Windows CE.
+  // CE has no environment variables.
+  return NULL;
+#elif defined(GTEST_OS_WINDOWS)  // We are on Windows proper.
+  // MSVC 8 deprecates getenv(), so we want to suppress warning 4996
+  // (deprecated function) there.
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4996)  // Temporarily disables warning 4996.
+  return getenv(name);
+#pragma warning(pop)           // Restores the warning state.
+#else  // We are on Linux or Mac OS.
+  return getenv(name);
+#endif
+}
+
+// Macro for referencing flags.
+#define GTEST_FLAG(name) FLAGS_gtest_##name
+
+// Macros for declaring flags.
+#define GTEST_DECLARE_bool(name) extern bool GTEST_FLAG(name)
+#define GTEST_DECLARE_int32(name) \
+    extern ::testing::internal::Int32 GTEST_FLAG(name)
+#define GTEST_DECLARE_string(name) \
+    extern ::testing::internal::String GTEST_FLAG(name)
+
+// Macros for defining flags.
+#define GTEST_DEFINE_bool(name, default_val, doc) \
+    bool GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_int32(name, default_val, doc) \
+    ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_string(name, default_val, doc) \
+    ::testing::internal::String GTEST_FLAG(name) = (default_val)
+
+// Parses 'str' for a 32-bit signed integer.  If successful, writes the result
+// to *value and returns true; otherwise leaves *value unchanged and returns
+// false.
+// TODO(chandlerc): Find a better way to refactor flag and environment parsing
+// out of both gtest-port.cc and gtest.cc to avoid exporting this utility
+// function.
+bool ParseInt32(const Message& src_text, const char* str, Int32* value);
+
+// Parses a bool/Int32/string from the environment variable
+// corresponding to the given Google Test flag.
+bool BoolFromGTestEnv(const char* flag, bool default_val);
+Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
+const char* StringFromGTestEnv(const char* flag, const char* default_val);
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
diff --git a/src/gtest/internal/gtest-string.h b/src/gtest/internal/gtest-string.h
new file mode 100644
index 0000000..3d20c0f
--- /dev/null
+++ b/src/gtest/internal/gtest-string.h
@@ -0,0 +1,280 @@
+// Copyright 2005, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file declares the String class and functions used internally by
+// Google Test.  They are subject to change without notice. They should not used
+// by code external to Google Test.
+//
+// This header file is #included by testing/base/internal/gtest-internal.h.
+// It should not be #included by other files.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
+
+#include <string.h>
+
+#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+// When using Google Test on the Mac as a framework, all the includes will be
+// in the framework headers folder along with gtest.h.
+// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on
+// the Mac and are not using it as a framework.
+// More info on frameworks available here:
+// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/
+// Concepts/WhatAreFrameworks.html.
+#include "gtest-port.h"  // NOLINT
+#else
+#include <gtest/internal/gtest-port.h>
+#endif  // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE)
+
+namespace testing {
+namespace internal {
+
+// String - a UTF-8 string class.
+//
+// We cannot use std::string as Microsoft's STL implementation in
+// Visual C++ 7.1 has problems when exception is disabled.  There is a
+// hack to work around this, but we've seen cases where the hack fails
+// to work.
+//
+// Also, String is different from std::string in that it can represent
+// both NULL and the empty string, while std::string cannot represent
+// NULL.
+//
+// NULL and the empty string are considered different.  NULL is less
+// than anything (including the empty string) except itself.
+//
+// This class only provides minimum functionality necessary for
+// implementing Google Test.  We do not intend to implement a full-fledged
+// string class here.
+//
+// Since the purpose of this class is to provide a substitute for
+// std::string on platforms where it cannot be used, we define a copy
+// constructor and assignment operators such that we don't need
+// conditional compilation in a lot of places.
+//
+// In order to make the representation efficient, the d'tor of String
+// is not virtual.  Therefore DO NOT INHERIT FROM String.
+class String {
+ public:
+  // Static utility methods
+
+  // Returns the input if it's not NULL, otherwise returns "(null)".
+  // This function serves two purposes:
+  //
+  // 1. ShowCString(NULL) has type 'const char *', instead of the
+  // type of NULL (which is int).
+  //
+  // 2. In MSVC, streaming a null char pointer to StrStream generates
+  // an access violation, so we need to convert NULL to "(null)"
+  // before streaming it.
+  static inline const char* ShowCString(const char* c_str) {
+    return c_str ? c_str : "(null)";
+  }
+
+  // Returns the input enclosed in double quotes if it's not NULL;
+  // otherwise returns "(null)".  For example, "\"Hello\"" is returned
+  // for input "Hello".
+  //
+  // This is useful for printing a C string in the syntax of a literal.
+  //
+  // Known issue: escape sequences are not handled yet.
+  static String ShowCStringQuoted(const char* c_str);
+
+  // Clones a 0-terminated C string, allocating memory using new.  The
+  // caller is responsible for deleting the return value using
+  // delete[].  Returns the cloned string, or NULL if the input is
+  // NULL.
+  //
+  // This is different from strdup() in string.h, which allocates
+  // memory using malloc().
+  static const char* CloneCString(const char* c_str);
+
+  // Compares two C strings.  Returns true iff they have the same content.
+  //
+  // Unlike strcmp(), this function can handle NULL argument(s).  A
+  // NULL C string is considered different to any non-NULL C string,
+  // including the empty string.
+  static bool CStringEquals(const char* lhs, const char* rhs);
+
+  // Converts a wide C string to a String using the UTF-8 encoding.
+  // NULL will be converted to "(null)".  If an error occurred during
+  // the conversion, "(failed to convert from wide string)" is
+  // returned.
+  static String ShowWideCString(const wchar_t* wide_c_str);
+
+  // Similar to ShowWideCString(), except that this function encloses
+  // the converted string in double quotes.
+  static String ShowWideCStringQuoted(const wchar_t* wide_c_str);
+
+  // Compares two wide C strings.  Returns true iff they have the same
+  // content.
+  //
+  // Unlike wcscmp(), this function can handle NULL argument(s).  A
+  // NULL C string is considered different to any non-NULL C string,
+  // including the empty string.
+  static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
+
+  // Compares two C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike strcasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL C string,
+  // including the empty string.
+  static bool CaseInsensitiveCStringEquals(const char* lhs,
+                                           const char* rhs);
+
+  // Formats a list of arguments to a String, using the same format
+  // spec string as for printf.
+  //
+  // We do not use the StringPrintf class as it is not universally
+  // available.
+  //
+  // The result is limited to 4096 characters (including the tailing
+  // 0).  If 4096 characters are not enough to format the input,
+  // "<buffer exceeded>" is returned.
+  static String Format(const char* format, ...);
+
+  // C'tors
+
+  // The default c'tor constructs a NULL string.
+  String() : c_str_(NULL) {}
+
+  // Constructs a String by cloning a 0-terminated C string.
+  String(const char* c_str) : c_str_(NULL) {  // NOLINT
+    *this = c_str;
+  }
+
+  // Constructs a String by copying a given number of chars from a
+  // buffer.  E.g. String("hello", 3) will create the string "hel".
+  String(const char* buffer, size_t len);
+
+  // The copy c'tor creates a new copy of the string.  The two
+  // String objects do not share content.
+  String(const String& str) : c_str_(NULL) {
+    *this = str;
+  }
+
+  // D'tor.  String is intended to be a final class, so the d'tor
+  // doesn't need to be virtual.
+  ~String() { delete[] c_str_; }
+
+  // Returns true iff this is an empty string (i.e. "").
+  bool empty() const {
+    return (c_str_ != NULL) && (*c_str_ == '\0');
+  }
+
+  // Compares this with another String.
+  // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0
+  // if this is greater than rhs.
+  int Compare(const String& rhs) const;
+
+  // Returns true iff this String equals the given C string.  A NULL
+  // string and a non-NULL string are considered not equal.
+  bool operator==(const char* c_str) const {
+    return CStringEquals(c_str_, c_str);
+  }
+
+  // Returns true iff this String doesn't equal the given C string.  A NULL
+  // string and a non-NULL string are considered not equal.
+  bool operator!=(const char* c_str) const {
+    return !CStringEquals(c_str_, c_str);
+  }
+
+  // Returns true iff this String ends with the given suffix.  *Any*
+  // String is considered to end with a NULL or empty suffix.
+  bool EndsWith(const char* suffix) const;
+
+  // Returns true iff this String ends with the given suffix, not considering
+  // case. Any String is considered to end with a NULL or empty suffix.
+  bool EndsWithCaseInsensitive(const char* suffix) const;
+
+  // Returns the length of the encapsulated string, or -1 if the
+  // string is NULL.
+  int GetLength() const {
+    return c_str_ ? static_cast<int>(strlen(c_str_)) : -1;
+  }
+
+  // Gets the 0-terminated C string this String object represents.
+  // The String object still owns the string.  Therefore the caller
+  // should NOT delete the return value.
+  const char* c_str() const { return c_str_; }
+
+  // Sets the 0-terminated C string this String object represents.
+  // The old string in this object is deleted, and this object will
+  // own a clone of the input string.  This function copies only up to
+  // length bytes (plus a terminating null byte), or until the first
+  // null byte, whichever comes first.
+  //
+  // This function works even when the c_str parameter has the same
+  // value as that of the c_str_ field.
+  void Set(const char* c_str, size_t length);
+
+  // Assigns a C string to this object.  Self-assignment works.
+  const String& operator=(const char* c_str);
+
+  // Assigns a String object to this object.  Self-assignment works.
+  const String& operator=(const String &rhs) {
+    *this = rhs.c_str_;
+    return *this;
+  }
+
+ private:
+  const char* c_str_;
+};
+
+// Streams a String to an ostream.
+inline ::std::ostream& operator <<(::std::ostream& os, const String& str) {
+  // We call String::ShowCString() to convert NULL to "(null)".
+  // Otherwise we'll get an access violation on Windows.
+  return os << String::ShowCString(str.c_str());
+}
+
+// Gets the content of the StrStream's buffer as a String.  Each '\0'
+// character in the buffer is replaced with "\\0".
+String StrStreamToString(StrStream* stream);
+
+// Converts a streamable value to a String.  A NULL pointer is
+// converted to "(null)".  When the input value is a ::string,
+// ::std::string, ::wstring, or ::std::wstring object, each NUL
+// character in it is replaced with "\\0".
+
+// Declared here but defined in gtest.h, so that it has access
+// to the definition of the Message class, required by the ARM
+// compiler.
+template <typename T>
+String StreamableToString(const T& streamable);
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_